Is there a good reason for always enclosing a define in parentheses in C?

后端 未结 9 1068
遇见更好的自我
遇见更好的自我 2020-12-01 02:33

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         


        
相关标签:
9条回答
  • 2020-12-01 03:23

    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.

    0 讨论(0)
  • 2020-12-01 03:27

    Whenever the define consists of a single token (one operand only, no operators), the parentheses are not needed because a single token (such as 100) is an indivisible atom when lexing and parsing.

    0 讨论(0)
  • 2020-12-01 03:30

    Since 100 is a single token, I doubt you'll find a corner case where the parentheses matter (for a single token!)

    It's still a good habit IMO, since they can matter when there are multiple tokens involved.

    0 讨论(0)
提交回复
热议问题