Clearly, there are times where #define
statements must have parentheses, like so:
#define WIDTH 80+20 int a = WIDTH * 2; // expect a==200 but a==120
So I always parenthesize, even when it's just a single number:
#define WIDTH (100)
Someone new to C asked me why I do this, so I tried to find an edge case where the absence of parentheses on a single number #define
causes issues, but I can't think of one.
Does such a case exist?
Using parentheses defensively reduces errors and, if not taken to excess, makes the code more readable. Subclause 6.5 of the C Standard defines the precedence of operation by the order of the subclauses.
The macro and its parameters should be enclosed in parentheses. When macro parameters or expression are not parenthesized, the intended logic may get disrupted after expanding the macro.
What are the parentheses for? In C brackets [] have a higher precedence than the asterisk * Good explanation from Wikipedia: To declare a variable as being a pointer to an array, we must make use of parentheses. This is because in C brackets ([]) have higher precedence than the asterisk (*).
Yes. The preprocessor concatenation operator (##
) will cause issues, for example:
#define _add_penguin(a) penguin ## a #define add_penguin(a) _add_penguin(a) #define WIDTH (100) #define HEIGHT 200 add_penguin(HEIGHT) // expands to penguin200 add_penguin(WIDTH) // error, cannot concatenate penguin and (100)
Same for stringization (#
). Clearly this is a corner case and probably doesn't matter considering how WIDTH
will presumably be used. Still, it is something to keep in mind about the preprocessor.
(The reason why adding the second penguin fails is a subtle detail of the preprocessing rules in C99 - iirc it fails because concatenating to two non-placeholder preprocessing tokens must always result in a single preprocessing token - but this is irrelevant, even if the concatenation was allowed it would still give a different result than the unbracketed #define
!).
All other responses are correct only insofar that it doesn't matter from the point of view of the C++ scanner because, indeed, a number is atomic. However, to my reading of the question there is no sign that only cases with no further preprocessor expansion should be considered, so the other responses are, even though I totally agree with the advice contained therein, wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With