I'm trying to define a macro like this:
#define SOME_DEF [[TTys getString] isEqualToString:ANOTHER_STRING]
and then doing the following:
#if SOME_DEF
...
#endif
[TTys getString] returns an NSString
ANOTHER_STRING is defined earlier as #define ANOTHER_STRING "hello"
I get the following error on the #if SOME_DEF line:
Invalid token at start of a preprocessor expression
Based on this SO question this might be caused by something that can't be resolved at compile time, but I have everything defined. My suspect is
the isEqualToString method, but I don't know of another way to do this.
When you write #if SOME_DEF the preprocessor resolves it into:
#if [[TTys getString] isEqualToString:ANOTHER_STRING]
This is not a valid condition for the #if preprocessor directive:
The ‘#if’ directive allows you to test the value of an arithmetic
expression, rather than the mere existence of one macro. Its syntax is
#if expression
controlled text
#endif /* expression */
expression is a C expression of integer type, subject to stringent restrictions. It may contain
Integer constants.
Character constants, which are interpreted as they
would be in normal code.
Arithmetic operators for addition,
subtraction, multiplication, division, bitwise operations, shifts,
comparisons, and logical operations (&& and ||). The latter two obey
the usual short-circuiting rules of standard C.
Macros. All macros in
the expression are expanded before actual computation of the
expression's value begins.
Uses of the defined operator, which lets
you check whether macros are defined in the middle of an ‘#if’.
Identifiers that are not macros, which are all considered to be the
number zero. This allows you to write #if MACRO instead of #ifdef
MACRO, if you know that MACRO, when defined, will always have a
nonzero value. Function-like macros used without their function call
parentheses are also treated as zero.
From the GCC documentation.
What you can do instead is using a runtime-evaluated regular if-statement:
if(SOME_DEF) {
...
}
Related
I'm new to Clang, and trying to write some clang-tidy checks. I want to find something that works as a "variable table", to check if some names are well-formed.
My intuition is like this:
To write redefinition code will sometimes cause an error, which is thrown out by Clang's diagnostics. like:
int main(){
int x;
int x; // error: redefinition
return 0;
}
From my perspective, clang may keep a dynamic variable table to check whether a new definition is compatible/overloading/error.
I tried to dive into clang source code and explored something:
Identifiertable, is kept by preprocessor, which marks all the identifiers, but does not do the semantic legal checking.
DeclContext, which seems to be an interface for users to use, a product produced by semantic checking.
My question is :
How Clang do the legal checking?
Am I able to get the variable table(If there exists such kind of things)?
If I cannot get such things, how could I know which variables are reachable from a location?
Thanks for your suggestions!
TLDR; see Answers below.
Discussion
All of your questions are related to one term of C standard, identifier, in C99-6.2.1-p1:
An identifier can denote an object; a function; a tag or a member of a structure, union, or
enumeration; a typedef name; a label name; a macro name; or a macro parameter.
Each identifier has its own scope, one of the following, according to C99-6.2.1-p2:
For each different entity that an identifier designates, the identifier is visible (i.e., can be
used) only within a region of program text called its scope.
Since what you are interested in are the variables inside a function (i.e., int x), then it should then obtain a block scope.
There is an process called linkage for the identifiers in the same scope, according to C99-6.2.2-p2:
An identifier declared in different scopes or in the same scope more than once can be
made to refer to the same object or function by a process called linkage.
This is exactly the one that put a constraint that there should be only one identifier for one same object, or in your saying, definition legally checking. Therefore compiling the following codes
/* file_1.c */
int a = 123;
/* file_2.c */
int a = 456;
would cause an linkage error:
% clang file_*
...
ld: 1 duplicate symbol
clang: error: linker command failed with exit code 1
However, in your case, the identifiers are inside the same function body, which is more likely the following:
/* file.c */
int main(){
int b;
int b=1;
}
Here identifier b has a block scope, which shall have no linkage, according to C99-6.2.2-p6:
The following identifiers have no linkage: an identifier declared to be anything other than
an object or a function; an identifier declared to be a function parameter; a block scope
identifier for an object declared without the storage-class specifier extern.
Having no linkage means that we cannot apply the rules mentioned above to it, that is, it should not be related to a linkage error kind.
It is naturally considered it as an error of redefinition. But, while it is indeed defined in C++, which is called One Definition Rule, it is NOT in C.(check this or this for more details) There is no exact definition for dealing with those duplicate identifiers in a same block scope. Hence it is an implementation-defined behavior. This might be the reason why with clang, the resulting errors after compiling the above codes (file.c) differs from the ones by gcc, as shown below:
(note that the term 'with no linkage' by gcc)
# ---
# GCC (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04))
# ---
$ gcc file.c
file.c: In function ‘main’:
file.c:4:6: error: redeclaration of ‘b’ with no linkage
int b=1;
^
file.c:3:6: note: previous declaration of ‘b’ was here
int b;
^
# ---
# CLANG (Apple clang version 13.0.0 (clang-1300.0.29.3))
# ---
% clang file.c
file.c:4:6: error: redefinition of 'b'
int b;
^
file.c:3:6: note: previous definition is here
int b=1;
^
1 error generated.
Answers
With all things above, I think it suffices to answer your questions:
How clang perform the definition legally checking?
For global variables, either clang or gcc would follow the C standard rules, that is to say, they handle the so-called "redefinition errors" by the process called Linkage. For local variables, it is undefined behavior, or more precisely, implementation-defined behavior.
In fact, They both view the "redefinition" as an error. Although variable names inside a function body would be vanished after compiled (you can verify this in the assembly output), it is undoubtedly more natural and helpful for letting them be unique.
Am I able to get the variable table(If there exists such kind of things)?
Having not so much knowledge about clang internals, but according to the standards quoted above, along with an analysis of compiling, we can infer that IdentifierTable might not much fit your needs, since it exists in "preprocessing" stage, which is before "linking" stage. To take a look how clang compiler deals with duplicate variables (or more formally, symbols), and how to store them, you might want to check the whole project of lld, or in particular, SymbolTable.
I'm trying to find any information parentheses syntax for macro arguments in GNU Assembler. E.g. I have following code:
.macro do_block, enc, in, rounds, rk, rkp, i
eor \in\().16b, \in\().16b, v15.16b
...
(taken from here)
What does paretheses in \in\().16b mean? Where to find documentaion for this syntax?
Okay, I've found the answer. This is special syntax to escape macro-argument name.
From the documentation:
Note that since each of the macargs can be an identifier exactly as any other one permitted by the target architecture, there may be occasional problems if the target hand-crafts special meanings to certain characters when they occur in a special position. For example:
...
problems might occur with the period character (‘.’) which is often allowed inside opcode names (and hence identifier names). So for example constructing a macro to build an opcode from a base name and a length specifier like this:
.macro opcode base length
\base.\length
.endm
and invoking it as ‘opcode store l’ will not create a ‘store.l’ instruction but instead > generate some kind of error as the assembler tries to interpret the text \base.\length.
The string \() can be used to separate the end of a macro argument from the following text. eg:
.macro opcode base length
\base\().\length
.endm
I am having a hard time with this problem.
"Write a flex code which recognizes a chain with alphabet {0,1}, with at least 5 char's, and to every consecutive 5 char's there will bee at least 3 1's"
I thought I have solved, but I am new using flex, so I am getting this "flex scanner push-back overflow".
here's my code
%{
#define ACCEPT 1
#define DONT 2
%}
delim [ \t\n\r]
ws {delim}+
comb01 00111|{comb06}1
comb02 01011|{comb07}1
comb03 01101|{comb08}1
comb04 01110|({comb01}|{comb09})0
comb05 01111|({comb01}|{comb09})1
comb06 10011|{comb10}1
comb07 10101|{comb11}1
comb08 10110|({comb02}|{comb12})0
comb09 10111|({comb02}|{comb12})1
comb10 11001|{comb13}1
comb11 11010|({comb03}|{comb14})0
comb12 11011|({comb03}|{comb14})1
comb13 11100|({comb04}|{comb15})0
comb14 11101|({comb04}|{comb15})1
comb15 11110|({comb05}|{comb16})0
comb16 11111|({comb05}|{comb16})1
accept {comb01}|{comb02}|{comb03}|{comb04}|{comb05}|{comb06}|{comb07}|{comb08}|{comb09}|{comb10}|{comb11}|{comb12}|{comb13}|{comb14}|{comb15}|{comb16}
string [^ \t\n\r]+
%%
{ws} { ;}
{accept} {return ACCEPT;}
{string} {return DONT;}
%%
void main () {
int i;
while (i = yylex ())
switch (i) {
case ACCEPT:
printf ("%-20s: ACCEPT\n", yytext);
break;
case DONT:
printf ("%-20s: Reject\n", yytext);
break;
}
}
Flex definitions are macros, and flex implements them that way: when it sees {defn} in a pattern, it replaces it with whatever defn was defined as (in parentheses, usually, to avoid operator precedence issues). It doesn't expand the macros in the macro definition, so the macro substitution might contain more definition references which in turn need to be substituted.
Since macro substitution is unconditional, it is not possible to use recursive macros, including macros which are indirectly recursive. Which yours are. Flex doesn't check for this condition, unlike the C preprocessor; it just continues substituting in an endless loop until it runs out of space.
(Flex is implemented using itself; it does the macro substitution using unput. unput will not resize the input buffer, so "runs out of space" here means that flex's internal flex's input buffer became full of macro substitutions.)
The strategy you are using would work fine as a context-free grammar. But that's not flex. Flex is about regular expressions. The pattern you want to match can be described by a regular expression -- the "grammar" you wrote with flex macros is a regular grammar -- but it is not a regular expression and flex won't make one out of it for you, unfortunately. That's your job.
I don't think it's going to be a very pretty regular expression. In fact, I think it's likely to be enormous. But I didn't try working it out..
There are flex tricks you could use to avoid constructing the regular expression. For example, you could build your state machine out of flex start conditions and then scan one character at a time, where each character scanned does a state transition or throws an error. (Use more() if you want to return the entire string scanned at the end.)
If I am using standard preprocessing then I may perform an indirect quote by:
#define foo bar
#define quoteme_(x) #x
#define quoteme(x) quoteme_(x)
and then just use quoteme(foo) to obtain "bar"
I want to do this, but using the pre-processor in traditional mode. I have attempted to just replace #x with 'x' but quoteme(foo) just returns 'foo'.
Any help is much appreciated.
Using the cpp that comes with GCC (4.8.1 tested), and the code (example.c):
#define foo bar
#define quoteme_(x) "x"
#define quoteme(x) quoteme_(x)
quoteme(foo)
The relevant part of the output from cpp -traditional example.c is:
"foo"
(and you can use single quotes in the replacement for quoteme_(x) similarly to obtain 'foo'). This is what you observed in the question.
AFAIK, there isn't a way to get 'bar' or "bar" out of the traditional preprocessor system. The pre-standard (traditional) systems were not standardized, and there were details where different systems behaved differently. However, macro arguments were expanded after replacement, rather than before as in C89 and later, which is what leads to the result you're seeing.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I may have made some syntax mistakes, but I can't understand why my code isn't working:
In top of .m file I wrote:
#define kCountry "Country";
In this case I got red warning from xCode - expected ]
Then in function body:
floatCountries = 74,2;
[[NSUserDefaults standardUserDefaults]setFloat:floatCountries forKey:kCountry];
float test= [[NSUserDefaults standardUserDefaults]floatForKey:kCountry];
NSLog(#"%f", test);
In that one - expected expression.
That may sound a bit stupid, but I want to simplify my code and use this, please help me! :)
Remove the semi-colon from the end of the define and add the '#':
#define kCountry #"Country"
Use:
#define kCountry #"Country"
You added a semicolon at the end.
And as this will be replaced for string value, you need to put #
To explain why this didn't work:
The semicolon
#define kCountry "Country";
In this case i got red warning from xCode - expected ]
There's no such thing as a “red warning”. Warnings are yellow; errors are red.
(Unless you turn on “Treat Warnings as Errors”; then, in a sense, all the warnings are red—because then they're errors.)
Anyway.
Preprocessor directives such as #define do not require a semicolon. If you include one, it becomes part of the directive.
The preprocessor replaces any macro with whatever you defined it as. In this case, you defined a macro named “kCountry” with the value “"Country;”. Note that the semicolon is part of the value—the directive ends at the end of the line, not at a semicolon.
Thus, when you go to use the macro:
[[NSUserDefaults standardUserDefaults]setFloat:floatCountries forKey:kCountry];
float test= [[NSUserDefaults standardUserDefaults]floatForKey:kCountry];
The preprocessor replaces the macro as follows:
[[NSUserDefaults standardUserDefaults]setFloat:floatCountries forKey:"Country";];
float test= [[NSUserDefaults standardUserDefaults]floatForKey:"Country";];
A semicolon can't go inside a statement; it must come after. Thus, the above statements are invalid.
The fix is to remove the semicolon from the line where you #defined the macro, so that the semicolon does not appear in the output:
[[NSUserDefaults standardUserDefaults]setFloat:floatCountries forKey:"Country"];
float test= [[NSUserDefaults standardUserDefaults]floatForKey:"Country"];
By the way, Xcode has an option in its Jump Bar to show you the complete preprocessed version of the code, as the compiler will see it. That can be handy when investigating macro problems.
So, that's one of the problems. The other one was…
The kind of string you used
"Country" is a C string. It's only usable with the C string and stdio libraries (including the functions printf, strcat, etc.) and various other APIs that require C strings (such as +[NSString stringWithUTF8String:] and +[NSString stringWithCString:encoding:]).
NSUserDefaults, like everything else in Cocoa that requires a string, requires a Cocoa string object—an NSString. The syntax for an NSString literal is the same, but with an # in front of it: #"Country".
Hence the version that works:
#define kCountry #"Country"
Which produces the preprocessed output:
[[NSUserDefaults standardUserDefaults]setFloat:floatCountries forKey:#"Country"];
float test= [[NSUserDefaults standardUserDefaults]floatForKey:#"Country"];
With no syntax errors and the right kind of string in both places, this is the version that will work.
Oh, and, as Anoop Vaidya already pointed out:
The number syntax
You tried to assign a number to a variable, but I think you'll find a different number there than you were expecting.
floatCountries = 74,2;
If you print the value of this variable with a statement such as:
NSLog(#"%f", floatCountries);
You'll find that the output is 2.0.
C has an operator called the comma operator, and it is simply x, y, where x and y can be any expression (ideally of types that are compatible with each other—e.g., both numbers).
The comma operator evaluates first the left-side expression, then the right-side expression, and itself evaluates to the right-side expression.
74,2 evaluates first the expression 74, and then the expression 2, and then evaluates to 2. Thus, you assign 2 (an int, which is converted automatically as needed) to the variable.
It may seem kind of silly to use this with literal numbers, and it is. The comma operator exists to be used with expressions that have side effects, such as expressions involving the ++ and -- operators.
Use of the comma operator is generally discouraged, because the resulting code is unclear: as a rule, each line should do one thing, but a line such as x = ++y, --z; does three things.
Nonetheless, it is valid, as you found. You should get a warning, though, if you have the “unused value” warning turned on (as you should), because half of the expression is, in fact, unused—you drop the 74 on the floor. Harmless, but a symptom that this isn't what you meant to do.
What you want is:
floatCountries = 74.2;