What predefined macro can I use to detect clang?
To get a list of all the predefined macros that the compiler uses, use this: clang -dM -E -x c /dev/null You can do the same for gcc.
To get a list of all the predefined macros that the compiler uses, use this: clang -dM -E -x c /dev/null You can do the same for gcc.
Code supporting arbitrary byte orders, ready to be put into a file called order32.h: #ifndef ORDER32_H #define ORDER32_H #include <limits.h> #include <stdint.h> #if CHAR_BIT != 8 #error “unsupported char size” #endif enum { O32_LITTLE_ENDIAN = 0x03020100ul, O32_BIG_ENDIAN = 0x00010203ul, O32_PDP_ENDIAN = 0x01000302ul, /* DEC PDP-11 (aka ENDIAN_LITTLE_WORD) */ O32_HONEYWELL_ENDIAN = 0x02030001ul /* Honeywell 316 (aka … Read more
Macros are error-prone because they rely on textual substitution and do not perform type-checking. For example, this macro: #define square(a) a * a works fine when used with an integer: square(5) –> 5 * 5 –> 25 but does very strange things when used with expressions: square(1 + 2) –> 1 + 2 * 1 … Read more
The warning directive is probably the closest you’ll get, but it’s not entirely platform-independent: #warning “C Preprocessor got here!” AFAIK this works on most compilers except MSVC, on which you’ll have to use a pragma directive: #pragma message ( “C Preprocessor got here!” )
I usually use this macro to find a number of params: #define NUMARGS(…) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) Full example: #include <stdio.h> #include <string.h> #include <stdarg.h> #define NUMARGS(…) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) #define SUM(…) (sum(NUMARGS(__VA_ARGS__), __VA_ARGS__)) void sum(int numargs, …); int main(int argc, char *argv[]) { SUM(1); SUM(1, 2); SUM(1, 2, 3); SUM(1, 2, 3, 4); return 1; } void sum(int numargs, … Read more
For Mac OS: #ifdef __APPLE__ For MingW on Windows: #ifdef __MINGW32__ For Linux: #ifdef __linux__ For other Windows compilers, check this thread and this for several other compilers and architectures.
If you can’t use parentheses and you don’t like Mike’s SINGLE_ARG solution, just define a COMMA: #define COMMA , FOO(std::map<int COMMA int>, map_var); This also helps if you want to stringify some of the macro arguments, as in #include <cstdio> #include <map> #include <typeinfo> #define STRV(…) #__VA_ARGS__ #define COMMA , #define FOO(type, bar) bar(STRV(type) \ … Read more
My initial reaction was #ifdef, of course, but I think #if actually has some significant advantages for this – here’s why: First, you can use DEBUG_ENABLED in preprocessor and compiled tests. Example – Often, I want longer timeouts when debug is enabled, so using #if, I can write this DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000); … instead … Read more
Combine the strategies to reduce the disadvantages of a single approach. I work in embedded systems so the following solution is based on the fact that integer and bitwise operators are fast, low memory & low in flash usage. Place the enum in a namespace to prevent the constants from polluting the global namespace. namespace … Read more
## is the preprocessor operator for concatenation. So if you use DEFINE_STAT(foo) anywhere in the code, it gets replaced with struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo; before your code is compiled. Here is another example from a blog post of mine to explain this further. #include <stdio.h> #define decode(s,t,u,m,p,e,d) m ## s ## u ## t #define begin … Read more