Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defined constants as printf format argument, why is '+ 0' added?

Tags:

c

I'm reading a book about C programming "Advanced Programming In The Unix Environment" and in the "UNIX Standardization and Implementations" chapter it shows a program that prints values for symbols in sysconf and pathconf, the code in this program has several lines that looks like this:

#ifdef ARG_MAX
    printf ("ARG_MAX defined to be %ld\n", (long) ARG_MAX + 0);
#else
    printf ("no symbol for ARG_MAX\n");
#endif

Whenever a defined constant is used as an argument for printf it's always followed by + 0, it doesn't seem to be doing anything because I tried to remove it and nothing happened. What's the point of adding a zero?

like image 503
user7342539 Avatar asked Jan 05 '17 01:01

user7342539


1 Answers

The empty #define mentioned by melpomene in a comment is why the + 0 trick is used.

If some header has #define ARG_MAX (with no value) — an improbable but not impossible state of affairs — the code will still compile, though whether the output is useful is a separate discussion. The blank replacement for ARG_MAX leaves (long) + 0 which is still valid. If, as you'd expect, the definition is an appropriately protected expression (probably within parentheses), adding 0 doesn't change the value.

In the ordinary course of events, when the preprocessor evaluates a conditional expression, any identifiers left over after expanding macros are mapped to zero (ISO/IEC 9899:2011 §6.10.1 Conditional inclusion):

¶4 … After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0, and then each preprocessing token is converted into a token. …

Although that's not immediately relevant to this question, it is why you sometimes see a conditional expression such as:

#if ARG_MAX + 0 > 131072
like image 58
Jonathan Leffler Avatar answered Nov 11 '22 04:11

Jonathan Leffler