If the function name is missing, as in your first example, then it is not a "parenthesis operator". It is simply a syntactic element of an expression that alters the association between operators and operands. In this case it simply does nothing. What you have is just an expression
"Hello world";
which evaluates to a value of char *
type, and that value is ignored. You can surround that expression in a redundant pair of ()
("Hello world");
which will not change anything.
In exactly the same way you can write
(5 + 3);
in the middle of your code and get an expression that evaluates to value 8
, which is immediately discarded.
Usually compilers generate no code for expression statements that have no side effects. In fact, in C language the result of every expression statement is discarded, so the only expression statements that "make sense" are expression statements with side effects. Compilers are normally fairly good at detecting effectless statements and discarding them (sometimes with a warning).
The warning could be annoying, so writing effectless expression statements like
"Hello world";
might not be a good idea. Typically compilers recognize a cast to void
as a request not to generate this warning
(void) "Hello world";
So you might consider redefining your macro accordingly.
Of course, using the above trace
technique, you have to remember that if you put something that does have a side effect as an argument for your macro
trace("%d\n", i++);
then in "disabled" form it will look as follows
("%d\n", i++);
(two subexpressions, chained by a comma operator into one expression). The side effect of incrementing i
persists in this case, it does not get disabled. The whole thing is equivalent to plain
i++;
Also if you use a function call as an argument
trace(get_trace_name());
the "disabled" form will look as
(get_trace_name());
and the compiler might not be smart enough to realize that the call to get_trace_name()
should be discarded. So, be careful when using your macro. Avoid arguments with side effects, avoid arguments with function calls, unless, of course, it is your intent to preserve the side effects when disabling the actual tracing.