I just saw this thread, describing how to add conditional macros:
Conditional value for a #define
but in my case I am defining a function within the condition.
#if TARGET_IPHONE_SIMULATOR
#define doSomething(){\
\\ does something
}\
#else
#define doSomething(){\
\\ does something else
}\
#endif
This does work, except I is causing gcc compiler to throw this warning:
"doSomething" redefined
This is the location of the previous arguments
Is there any workaround to help getting rid of the warnings?
UPDATE:
So I tried including the condition inside my definition:
#define doSomething(){\
#if TARGET_IPHONE_SIMULATOR
\\ do something
#else
\\ do something else
#endif
}\
but that throws an error:
error: '#' is not followed by a macro parameter.
I found the answer to my question here.
Conclusion:
you cannot include #ifdef etc... inside #define, because there should only be one pre-processing directive per line.
So although we can break the line with a backslash '\' this helps writing readable multiline macros,
but the preprocessor will see it as one line:
#define doSomething(){ #if TARGET_IPHONE_SIMULATOR ... #endif }
Which throws this error:
error: '#' is not followed by a macro parameter.
That makes sense, so I will have to rethink my implementation.
There is a quirk in your thinking which is by analogy/ extension. doSomething() has to be viewed as a function-like macro. As such its definition is ambivalent. Zoom out and see below:
doSomething() {
#if TARGET_IPHONE_SIMULATOR
// conditionally compiled code
#else
// platform-specific code
#endif
}
Also, this might address the error you received:# and ## have special purposes inside macro definitions. # is used to surround a macro parameter with double quotes. ## is used to concatenate two macro parameters. Example:#define ABC(X) #XABC(hello) results in "hello".#define XYZ(X,Y) X##YXYZ(O,K) results in OK.
Note that this feature is (possibly) unique to ANSI C.
Also, why would you be using a macro like this? Might a function work better for you?
One option to consider is creating a condition in a macro that will resolve at compile time. Consider the following:
If I would like to call a different function based on the value of 'c' as a pre-processor action, I can define a macro that checks the value of 'c' statically.
#define AorB(c) ((c>0) ? (Do_A(c)) : (Do_B(c)))
Then if you configure a level of optimization that removes branches that are never reachable, it should strip out which ever case wasn't performed. This may not exactly be what you were looking for.
Related
I have some testing code in Fortran which basically looks like
#define test1 0
#define test2 0
#define test3 0
...
#if test1
call test1()
#endif
#if test2
call test2()
#endif
#if test3
call test3()
#endif
...
At compilation, i want to change those values using -Dtest1=1.
I've seen some answers (like here) where they say you need to put
#ifndef test1
#define test1 0
#endif
But i have a lot of those and i would prefer not to add 40 lines of definition code.
Will compilation command -D flag take priority over my hard definition without the if clause?
EDIT : So i just tested it (which i should have done anyway before asking...) and compiler -D flag does not take priority over my own definition and just pulls out a warning . So any way for it to take priority and always use the compiler flags without passing through ifndef clauses?
-D effectively adds a #define at the beginning, before reading the input. So it would be just like adding an additional #define in your source code, which would naturally produce an error (or warning) about redefining the macro.
If you want to avoid that error, use the #ifndef idiom, just like everyone else does.
Not including the #ifndef guard to prevent multiple header file inclusions, does not throw compile error. Why is that?
// main.c
#include <stdio.h>
#include "declare.h"
#include "declare.h" //Shouldn't I get compiler error here
int main(){
printf("Hello World\n");
}
// declare.h
#define a 1 //just this define in declare.h file
Command used to compile: gcc main.c -std=c89
Including a header multiple times is not an error, either with or without guards.
Guards prevent you from redefining objects and functions, when you do so.
But you haven't done that. You've just redefined a macro with the same value it had before. Which is fine.
You can test this by just compiling the following file:
#define a 1
#define a 1
It's fine.
[C89: 6.8.3]: [..] An identifier currently defined as a macro without use of lparen (an object-like macro) may be redefined by another #define preprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical. [..]
Start putting more complex stuff in that header and you'll see a problem.
I recently got the following error when trying to compile with gcc:
error: missing binary operator before token "("
Web and SO searches came up with several specific examples of this error, with specific code changes to fix them. But I found no general description of what condition causes this error to be issued.
When and why does gcc emit this error?
This is not a compiler error, it is a preprocessor error. It occurs when the preprocessor encounters invalid syntax while trying to evaluate an expression in a #if or #elif directive.
One common cause is the sizeof operator in an #if directive:
For example:
#define NBITS (sizeof(TYPE)*8)
//later
#if (NBITS>16) //ERROR
This is an error because sizeof is evaluated by the compiler, not the preprocesor.
Type casts are also not valid preprocessor syntax:
#define ALLBITS ((unsigned int) -1)
//later
#if (ALLBITS>0xFFFF) //ERROR
The rules for what can be in a valid expression are here.
Note also that #if will evaluate an undefined macro as 0, unless it looks like it takes arguments, in which case you also get this error:
So if THIS is undefined:
#if THIS == 0 //valid, true
#if THIS > 0 //valid, false
#if THIS() == 0 //invalid. ERROR
Typos in your #if statement can also cause this message.
If you are on Linux, make sure that you do not have a header named features.h inside your project files.
I had one with this name, which resulted in:
/usr/include/x86_64-linux-gnu/bits/huge_val.h:25: error: function pointer expected
or
/usr/include/bits/huge_val.h:26:18: error: missing binary operator before token
"("
That is because some system headers like huge_val.h use macros like __GNUC_PREREQ that are defined by /usr/include/features.h (learn more about this header in this SO question).
In my case I first saw this error when I started to use gcc's -I option which suddenly made gcc select my project include directory before the default system include directories.
You get this error sometimes if you have -fno-operator-names in your compiler flags. I suffered from the exact error while building json and this solved it.
check the direct. no space,no special
exp:
add_subdirectory(Main)->add_subdirectory(main)
I would like to know if there is a way to get rid of CDT syntax error warnings when using gcc's "__attribute__" keyword.
It goes without saying that I would not like to switch off CDT syntax check.
The "ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT" definition (from ams's answer) really extsts and it called __CDT_PARSER__. For example:
#ifdef __CDT_PARSER__
#define __FILE__ "<file>"
#define __LINE__ (-1)
#define __DATE__ "<date>"
#define __TIME__ "<time>"
#endif // #ifdef __CDT_PARSER__
Hope this will be helpful.
I've not tried it, and I've not used Eclipse for some time, but here's an idea:
In the CDT settings for Eclipse (or maybe just your project) set up a predefined macro (I seem to remember you can tell it what the compiler auto-defines) named __attribute__ that takes one parameter, and expands to nothing.
Maybe I haven't explained that right. Let me try again with an example. Basically, the aim is to define a macro that works like this:
#if ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT
#define __attribute__(X) /* nothing */
#endif
but without putting anything actually in your code.
Project->Properties->C/C++ general->Path and Symbols->Symbols
Add->
Name: __attribute__(X)
Value: (leave blank)
Related links: You can use this technique basically with any offending keyword
ziu's answer is also working for XC8 Microchip compilers
Name: __interrupt
Value: (leave blank)
The function prototype now is clean:
void __interrupt ISRs(void);
And Eclipse won't complain about it.
How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.