Using preprocessor conditionals in macro functions with double parentheses - c

Given:
#define TRACE(x) do { if (DEBUG) dbg_print x; } while (0)
I want:
TRACE((
"Message: %s"
#ifdef MYDEF
"Additional stuff"
#endif
, msg));
But gives error:
error C2121: '#' invalid character : possibly the result of a macro expansion
error C2146: syntax error : missing ')' before identifier 'ifdef'
error C2121: '#' invalid character : possibly the result of a macro expansion
error C2059: syntax error : ')'
I know I can easily resolve this by writing two different TRACE calls and using #ifdef...#else...#endif, but the above is only a simplified case. My actual use case involve multiple #ifdef that controls both the format string and the arguments, so it's not practical write multiple trace calls (e.g. with 3 ifdef, I'll need 2^3 = 8 different calls to take care of all the possible combinations). Is there a way around this?

Some compilers will compile your code through compiler extension, but it is not portable. You can work around this issue by conditionally defining another macro, and using its result in a call of TRACE, like this:
#ifdef MYDEF
#define IF_MY(x,y) x y
#else
#define IF_MY(x,y) x
#endif
Now you can write your TRACE as follows:
TRACE((IF_MY("Message: %s", "Additional stuff"), msg));
Demo #1.
it seems like it will run into scalability issues.
That impression is incorrect. You can scale this approach quite easily to as many variables as you wish without running into combinatorial explosion. Here is an example of adding a second variable:
#ifdef YOURDEF
#define IF_MY_YOUR(x,y,z) IF_MY(x,y) z
#else
#define IF_MY_YOUR(x,y,z) IF_MY(x,y)
#endif
Now you can use the combined macro in your TRACE:
TRACE((IF_MY_YOUR("Message: %s", "Additional stuff", "More stuff"), msg));
Demo #2 - Both MYDEF and YOURDEF are defined
Demo #2 - Only YOURDEF is defined
Demo #2 - Only MYDEF is defined
Demo #2 - Neither MYDEF or YOURDEF is defined
What if I have additional arguments that are to be controlled by #define too?
Do the same thing for parameters, with commas in between x and y parts. The call of TRACE would look like this:
TRACE((
IF_MY_YOUR_FMT("Message: %s", "Additional %s stuff", "More %s stuff")
, IF_MY_YOUR_ARG(msg1, msg2, msg3)
));

Related

static assert for C90 on gcc

static_assert() is a pretty great capability available since C11.
For pre-C11 compilers though, this capability must be emulated.
It's not too hard, there are many examples available over Internet.
For example :
#define STATIC_ASSERT(CONDITION, MSG) \
typedef char static_assert_##MSG[(CONDITION)?1:-1]
This makes it possible to transfer an error message in the condition, which is handy to explain what's going wrong if it ever gets triggered.
However, this MSG is a lot different from the one in C11's static_assert() :
It must be a single word
It must use only identifier characters
It cannot be a string with double quotes
This is so different from C11's static_assert() that it seems impossible to create a macro which would switch transparently between the C11 and the C90 version depending on the compiler.
In an effort to accept an error message which "looks like C11", aka a string with double quote, I've tested a new macro :
#define STATIC_ASSERT(CONDITION, MSG) \
typedef char static_assert[((void)(MSG), ((CONDITION)?1:-1))]
Using the , comma operator, this macro should accept MSG as a string, and just disregard it. But it will be displayed in case of error, which is the intention.
It works fine on clang, but not of gcc : error: variably modified at file scope.
I'm trying to understand why, and if there is a work around
If you replace the typedef-array-trick with the enum-trick, then you will get something that seems to work with both clang and gcc:
#define CONDITION 1
#define TOKENPASTE(a, b) a ## b // "##" is the "Token Pasting Operator"
#define TOKENPASTE2(a,b) TOKENPASTE(a, b) // expand then paste
#define static_assert(x, msg) enum { TOKENPASTE2(ASSERT_line_,__LINE__) \
= 1 / (msg && (x)) }
static_assert( CONDITION, "This should pass");
static_assert(!CONDITION, "This should fail");
This gives me, with gcc for example, on line 9 of foo.c:
foo.c:9: warning: division by zero [-Wdiv-by-zero]
static_assert(!CONDITION, "This should fail");
^
foo.c:9: error: enumerator value for 'ASSERT_line_9' is not an integer constant
static_assert(!CONDITION, "This should fail");
^~~~~~~~~~~~~
(Here the gcc switch -ftrack-macro-expansion=0 is used, as the extra error messages are not that helpful and just add noise.)
Note that some mangling of the name is still necessary, which you omitted. Here the text ASSERT_line_ is combined with the variable __LINE__. This ensures a unique name, provided:
You don't use it twice on a single line.
You don't use it in header files (or trust to luck).
Your code doesn't happen to use the identifiers like ASSERT_line_9 elsewhere.
For header files, you will need to add somewhere a single word with only identifier characters. For example:
#define static_assert3(x, msg, file) enum { TOKENPASTE2(file,__LINE__) = \
1 / (msg && (x)) }
#define static_assert(x, msg) static_assert3(x, msg, my_header_h_)
If this fails on line 17, gcc will give an error such as:
error: enumerator value for 'my_header_h_17' is not an integer constant
An alternative for the mangling in header files is to replace __LINE__ with __COUNTER__. I've not used it, because it is non-standard and because clang was slow to adopt it. But now it has been in gcc, msvc, and clang for about five years.
You could try the same modification with your typedef-array idea, and replace the comma operator with &&. Then your gcc error changes into a warning. For example, modifying your godbolt example to:
typedef char static_assert_2["hello world!" && (CONDITION) ? 1 : -1];
gives the unwanted warning: variably modified 'static_assert_2' at file scope for gcc.
One-liner
#define STATIC_ASSERT(CONDITION, MSG) { typedef char test[(CONDITION)?1:-1]; (void)(test*) #MSG; } (void)0

Eclipse CDT syntax error for macro using _Generic keyword

I'm using Oxygen with CDT 9.3.0 built-in.
When I use a macro I defined that uses _Generic, all those macro uses are underlined with "syntax error", but the project compiles fine (which is setup to use my makefiles).
After reading a similar so question, and since _Generic begin from C11 possibly not supported by eclipse's code analysis, I tried defining a symbol for my macro definition to empty but it didn't work. (At project settings, C/C++ General->Paths and Symbols->Symbols Tab, GNU C, added symbol CONVERT(...) without a value and added a symbol CONVERT(X), and CONVERT() and CONVERT without a value).
For example my macro is:
#define FIRST_(_1, ...) _1
#define FIRST(...) FIRST_(__VA_ARGS__, _1, _2, _3)
#define CONVERT(...) \
_Generic((FIRST(__VA_ARGS__)), \
char* : toText, \
int : toInt, \
) (__VA_ARGS__)
and usage point, that gives the syntax error:
void* test = CONVERT("testme");
As #ErikW pointed out, _Generic is a C11 feature that Eclipse CDT's parser does not support yet. This bug tracks adding support for it.
(By the way, contributions to Eclipse CDT's C11 support are very welcome!)
It is possible to work around this using macros.
The problem with trying to define another version of the CONVERT(...) macro in "Paths and Symbols" is that the macros defined there are treated as if you wrote them at the very top of your file. A subsequent redefinition in your actual code overwrites the definition from "Paths and Symbols".
I can think of two approaches to go about this:
Approach 1
CDT defines a special macro __CDT_PARSER__ which evaluates to true when it's parsing the code, but false when the code is actually compiled.
You can take advantage of this to define a different version of CONVERT(...) for CDT's purposes:
#ifdef __CDT_PARSER__
#define CONVERT(...)
#else
#define CONVERT(...) \
_Generic((FIRST(__VA_ARGS__)), \
char* : toText, \
int : toInt, \
) (__VA_ARGS__)
#endif
This almost works, but not quite. We still get a syntax error, because this line:
void* test = CONVERT("testme", 42);
will now expand to:
void* test = ;
As you can see, we don't actually want an empty expansion for CONVERT(...). We want an expansion that will parse as a variable's initializer. 0 will work:
#ifdef __CDT_PARSER__
#define CONVERT(...) 0
#else
...
#endif
Approach 2
Instead of defining a different version of CONVERT(...), we could define _Generic(...) itself to be a macro for CDT's purposes.
This time, we can do it in "Paths and Symbols", because there is no redefinition of _Generic(...) in the code that would mess it up.
So let's define a symbol in "Paths and Symbols", with _Generic(...) as the name and an empty value.
Now, this line:
void* test = CONVERT("testme", 42);
will expand to:
void* test = _Generic((FIRST("testme", 42)), \
char* : toText, \
int : toInt, \
) ("testme", 42)
which will in turn expand to:
void* test = ("testme", 42);
which parses (("testme", 42) parses as a parenthesized comma-expression and is thus a valid initializer).
This approach has the advantage that you don't need to modify your actual code, and that it handles all uses of the _Generic macro rather than just the one in CONVERT.
On the other hand, it's possible that for some other uses of the _Generic macro, this particular expansion won't parse. If that's the case, you might be able to come up with a different expansion that will parse for all uses, or else you can go with Approach 1.

Macro to turn off printf statements

What MACRO can be used to switch off printf statements, rather than removing them all for deployment builds, I just want to switch them off, skip them, ignore them.
EDIT: I personally use gcc, but code is part of a larger project which will be compiled on a Panda board running Ubuntu.
Not exactly what you ask for, but I use this construct in my code for debug output when I do not have a proper logging system handy:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
So I can do this all over my code
SPAM(("foo: %d\n", 42));
and then disable all of them by changing 1 to 0 in #if above.
But if you have variadic macro support in all compilers that you write code for, then you may go for other answers and just redefine printf. (That being said, I find it useful to distinct debugging prints from regular ones in code — using a different function name helps readability.)
Note that you also can redirect stdout to the /dev/null, but I assume that you want to get rid from runtime overhead as well.
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
See also C #define macro for debug printing which discusses some important issues closely related to this.
Two options, either:
#define printf(...)
(requires C99 variadic macro parameters), you need to put it in some common header file which is never included before stdio.h, if there is one..
Or you can tell the linker to link it to something else, in GCC you would define
int wrap_printf(void) {return 0;}
and link using
--wrap printf
All that said, you should probably not be using printf for printing debug output, but rather a macro or utility function (which in turn can use printf if you'd like) which you have better control over.
Hope that helps.
If you want to avoid the potential warning that Jonathan's answer may give you and if you don't mind an empty call to printf you could also do something like
#define printf(...) printf("")
This works because C macros are not recursive. The expanded printf("") will just be left as such.
Another variant (since you are using gcc) would be something like
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
and in one compilation unit
int ignore_printf(char const*, ...)
I use to prefix the debug printf()s (not all of them) with PDEB.
For the debug builds, I compile with -DPDEB= (nothing)
For the release builds, I compile with -DPDEB="0&&" or -DPDEB="0 && "
That way, the following code (test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
outputs:
either (in release mode):
normal print
either (in debug mode):
normal print
debug print
Ideally, one could aim for turning the PDEB into the "//" (comments mark), except that this is not possible under the standard pre-/processing chain.
Another possibility would be something like freopen("/dev/null", "w", stdout);
This doesn't exactly disable printf though -- it's roughly equivalent to running your program with stdout redirected to /dev/null, like: ./myprog > /dev/null at the shell prompt.
I included #define printf // in common header file. It will suppress all the printf.
Below simple function serves the purpose, I use the same.
int printf(const char *fmt, ...)
{
return (0)
}
Use this macro to enable or disable the printf.
//Uncomment the following line to enable the printf function.
//#define ENABLE_PRINTF
#ifdef ENABLE_PRINTF
#define DEBUG_PRINTF(f,...) printf(f,##__VA_ARGS__)
#else
#define DEBUG_PRINTF(f,...)
#endif
Then call "DEBUG_PRINTF" instead of "printf".
For example:
DEBUG_PRINTF("Hello world: %d", whateverCount);
I have used two macros for this. The first one defines the condition to print. In this simple example we print any time the parameter is not zero. More complex expressions can be used.
The second one determines, based on the first macro, to call or not printf.
If the condition can be determined by the compiler (with the right optimization settings) no code is generated.
If the condition cannot be determined at compile time then will be at run time. One of the advantages of this method is that if printf is not going to happen then the whole printf is not evaluated avoiding many conversions to string that can happen in a complex printf statement.
#define need_to_print(flag) ((flag) != 0))
#define my_printf(debug_level, ...) \
({ \
if(need_to_print(debug_level)) \
printf(__VA_ARGS__); \
})
to use it call my_printf instead of printf and add a parameter at the beginning for the print condition.
my_printf(0, "value = %d\n", vv); //this will not print
my_printf(1, "value = %d\n", vv); //this will print
my_printf(print_debug, "value = %d\n", vv); //this will print if print_debug != 0
the ( ... ) parenthesis surrounding the macro make it a single statement.

#define LOG_MSG(...) for debugging

How does the following code work?
#define ENABLE_DEBUG 1
#if ENABLE_DEBUG
#define LOG_MSG printf
#else
#define LOG_MSG(...)
#endif
Depending on the value of ENABLE_DEBUG, LOG_MSG is either defined to be an alias for printf() or it is defined as a no-op macro. It is implied that you can change the value to 0 to disable debugging. This is a common technique for making it easy to switch between debugging builds which display lots of output and release builds which are quiet.
#define LOG_MSG printf
This makes it an alias for printf().
#define LOG_MSG(...) /* empty */
And this defines it as an empty macro. Notice that here it has a set of parentheses, which means the macro takes parameters. It has nothing afterwards which means it expands to absolutely nothing. And the ... indicates that this macro can take a varying number of arguments. This syntax is a C99 extension so it may not be available on older C compilers.
LOG_MSG("file not found\n");
The result is that a LOG_MSG() call will either print a message or do nothing depending on whether logging is enabled.
// If ENABLE_DEBUG is non-zero, a debugging printout:
printf("file not found\n");
// If ENABLE_DEBUG is zero, an empty statement:
;
For what it's worth, whoever authored this macro could've done a better job by replacing the first definition with one using the ... syntax (which he/she is clearly familiar with), printing to stderr instead of stdout:
#define LOG_MSG(...) fprintf(stderr, __VA_ARGS__)
This uses the preprocessor to change code before compilation.
If ENABLE_DEBUG is defined as 1, whenever the preprocessor sees
LOG_MSG("something happened");
It will replace it with
printf("something happened");
If it is defined as 0, or not defined it will replace it with nothing (as the other answer that has just been published says).

What are the applications of the ## preprocessor operator and gotchas to consider?

As mentioned in many of my previous questions, I'm working through K&R, and am currently into the preprocessor. One of the more interesting things — something I never knew before from any of my prior attempts to learn C — is the ## preprocessor operator. According to K&R:
The preprocessor operator ##
provides a way to concatenate actual
arguments during macro expansion. If a
parameter in the replacement text is
adjacent to a ##, the parameter is
replaced by the actual argument, the
## and surrounding white space are
removed, and the result is re-scanned.
For example, the macro paste
concatenates its two arguments:
#define paste(front, back) front ## back
so paste(name, 1) creates the token
name1.
How and why would someone use this in the real world? What are practical examples of its use, and are there gotchas to consider?
One thing to be aware of when you're using the token-paste ('##') or stringizing ('#') preprocessing operators is that you have to use an extra level of indirection for them to work properly in all cases.
If you don't do this and the items passed to the token-pasting operator are macros themselves, you'll get results that are probably not what you want:
#include <stdio.h>
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
#define BAD_PASTE(x,y) x##y
#define BAD_STRINGIFY(x) #x
#define SOME_MACRO function_name
int main()
{
printf( "buggy results:\n");
printf( "%s\n", STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
printf( "\n" "desired result:\n");
printf( "%s\n", STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
}
The output:
buggy results:
SOME_MACRO__LINE__
BAD_PASTE( SOME_MACRO, __LINE__)
PASTE( SOME_MACRO, __LINE__)
desired result:
function_name21
CrashRpt: Using ## to convert macro multi-byte strings to Unicode
An interesting usage in CrashRpt (crash reporting library) is the following:
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
//Note you need a WIDEN2 so that __DATE__ will evaluate first.
Here they want to use a two-byte string instead of a one-byte-per-char string. This probably looks like it is really pointless, but they do it for a good reason.
std::wstring BuildDate = std::wstring(WIDEN(__DATE__)) + L" " + WIDEN(__TIME__);
They use it with another macro that returns a string with the date and time.
Putting L next to a __ DATE __ would give you a compiling error.
Windows: Using ## for generic Unicode or multi-byte strings
Windows uses something like the following:
#ifdef _UNICODE
#define _T(x) L ## x
#else
#define _T(x) x
#endif
And _T is used everywhere in code
Various libraries, using for clean accessor and modifier names:
I've also seen it used in code to define accessors and modifiers:
#define MYLIB_ACCESSOR(name) (Get##name)
#define MYLIB_MODIFIER(name) (Set##name)
Likewise you can use this same method for any other types of clever name creation.
Various libraries, using it to make several variable declarations at once:
#define CREATE_3_VARS(name) name##1, name##2, name##3
int CREATE_3_VARS(myInts);
myInts1 = 13;
myInts2 = 19;
myInts3 = 77;
Here's a gotcha that I ran into when upgrading to a new version of a compiler:
Unnecessary use of the token-pasting operator (##) is non-portable and may generate undesired whitespace, warnings, or errors.
When the result of the token-pasting operator is not a valid preprocessor token, the token-pasting operator is unnecessary and possibly harmful.
For example, one might try to build string literals at compile time using the token-pasting operator:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
On some compilers, this will output the expected result:
1+2 std::vector
On other compilers, this will include undesired whitespace:
1 + 2 std :: vector
Fairly modern versions of GCC (>=3.3 or so) will fail to compile this code:
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
The solution is to omit the token-pasting operator when concatenating preprocessor tokens to C/C++ operators:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
The GCC CPP documentation chapter on concatenation has more useful information on the token-pasting operator.
This is useful in all kinds of situations in order not to repeat yourself needlessly. The following is an example from the Emacs source code. We would like to load a number of functions from a library. The function "foo" should be assigned to fn_foo, and so on. We define the following macro:
#define LOAD_IMGLIB_FN(lib,func) { \
fn_##func = (void *) GetProcAddress (lib, #func); \
if (!fn_##func) return 0; \
}
We can then use it:
LOAD_IMGLIB_FN (library, XpmFreeAttributes);
LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
LOAD_IMGLIB_FN (library, XpmReadFileToImage);
LOAD_IMGLIB_FN (library, XImageFree);
The benefit is not having to write both fn_XpmFreeAttributes and "XpmFreeAttributes" (and risk misspelling one of them).
A previous question on Stack Overflow asked for a smooth method of generating string representations for enumeration constants without a lot of error-prone retyping.
Link
My answer to that question showed how applying little preprocessor magic lets you define your enumeration like this (for example) ...;
ENUM_BEGIN( Color )
ENUM(RED),
ENUM(GREEN),
ENUM(BLUE)
ENUM_END( Color )
... With the benefit that the macro expansion not only defines the enumeration (in a .h file), it also defines a matching array of strings (in a .c file);
const char *ColorStringTable[] =
{
"RED",
"GREEN",
"BLUE"
};
The name of the string table comes from pasting the macro parameter (i.e. Color) to StringTable using the ## operator. Applications (tricks?) like this are where the # and ## operators are invaluable.
You can use token pasting when you need to concatenate macro parameters with something else.
It can be used for templates:
#define LINKED_LIST(A) struct list##_##A {\
A value; \
struct list##_##A *next; \
};
In this case LINKED_LIST(int) would give you
struct list_int {
int value;
struct list_int *next;
};
Similarly you can write a function template for list traversal.
The main use is when you have a naming convention and you want your macro to take advantage of that naming convention. Perhaps you have several families of methods: image_create(), image_activate(), and image_release() also file_create(), file_activate(), file_release(), and mobile_create(), mobile_activate() and mobile_release().
You could write a macro for handling object lifecycle:
#define LIFECYCLE(name, func) (struct name x = name##_create(); name##_activate(x); func(x); name##_release())
Of course, a sort of "minimal version of objects" is not the only sort of naming convention this applies to -- nearly the vast majority of naming conventions make use of a common sub-string to form the names. It could me function names (as above), or field names, variable names, or most anything else.
I use it in C programs to help correctly enforce the prototypes for a set of methods that must conform to some sort of calling convention. In a way, this can be used for poor man's object orientation in straight C:
SCREEN_HANDLER( activeCall )
expands to something like this:
STATUS activeCall_constructor( HANDLE *pInst )
STATUS activeCall_eventHandler( HANDLE *pInst, TOKEN *pEvent );
STATUS activeCall_destructor( HANDLE *pInst );
This enforces correct parameterization for all "derived" objects when you do:
SCREEN_HANDLER( activeCall )
SCREEN_HANDLER( ringingCall )
SCREEN_HANDLER( heldCall )
the above in your header files, etc. It is also useful for maintenance if you even happen to want to change the definitions and/or add methods to the "objects".
SGlib uses ## to basically fudge templates in C. Because there's no function overloading, ## is used to glue the type name into the names of the generated functions. If I had a list type called list_t, then I would get functions named like sglib_list_t_concat, and so on.
I use it for a home rolled assert on a non-standard C compiler for embedded:
#define ASSERT(exp) if(!(exp)){ \
print_to_rs232("Assert failed: " ## #exp );\
while(1){} //Let the watchdog kill us
I use it for adding custom prefixes to variables defined by macros. So something like:
UNITTEST(test_name)
expands to:
void __testframework_test_name ()
One important use in WinCE:
#define BITFMASK(bit_position) (((1U << (bit_position ## _WIDTH)) - 1) << (bit_position ## _LEFTSHIFT))
While defining register bit description we do following:
#define ADDR_LEFTSHIFT 0
#define ADDR_WIDTH 7
And while using BITFMASK, simply use:
BITFMASK(ADDR)
It is very useful for logging. You can do:
#define LOG(msg) log_msg(__function__, ## msg)
Or, if your compiler doesn't support function and func:
#define LOG(msg) log_msg(__file__, __line__, ## msg)
The above "functions" logs message and shows exactly which function logged a message.
My C++ syntax might be not quite correct.

Resources