simplecpp icon indicating copy to clipboard operation
simplecpp copied to clipboard

Function-like macro not expanded a second time in some cases

Open dummyunit opened this issue 4 years ago • 2 comments

Preprocessing of this code with simplecpp:

#define CAT(a, b) CAT2(a, b)
#define CAT2(a, b) a ## b
#define FOO x
#define BAR() CAT(F, OO)
#define BAZ CAT(B, AR)()
BAZ

produces this result:

CAT ( F , OO )

All mainstream preprocessors (GCC, Clang, MSVC) produce this result (https://godbolt.org/z/9GhhTarE3):

x

It seems that simplecpp decides to not expand CAT a second time during evaluation of BAZ. I don't know if this is correct from the point of view of the standard.

Some additional observations:

  1. If the last line is replaced with CAT(B, AR)() then all preprocessors produce the same result: x.
  2. If BAR() is converted from function-like macro to regular macro:
    #define BAR CAT(F, OO)
    #define BAZ CAT(B, AR)
    
    then all preprocessors produce the same result: CAT ( F , OO ).

dummyunit avatar Jan 18 '22 21:01 dummyunit

I don't know if this is correct from the point of view of the standard. it is not

#define CAT(a, b) CAT2(a, b)
#define CAT2(a, b) a ## b
#define FOO x
#define BAR() CAT(F, OO)
#define BAZ CAT(B, AR)()
BAZ
// expansion:

BAZ -> CAT(B, AR())
 CAT(B, AR()) -> B -> B
  CAT(B, AR()) -> AR() -> AR()
   CAT(a, b) -> CAT2(B, AR())
    CAT2(a, b) -> B##AR() -> BAR()
     BAR() -> CAT(F, OO)
      // should CAT be ommited from expansion since it was already expanded?
      // not sure, think standard allows for one more expansion before it stops expanding
      // otherwise gcc would not produce x
      CAT(a, b) -> CAT2(F, OO)
       // should CAT2 be ommited from expansion since it was already expanded?
       // not sure, think standard allows for one more expansion before it stops expanding
       // otherwise gcc would not produce x
       CAT2(a, b) -> F##OO -> FOO
        FOO -> x

mgood7123 avatar Jan 20 '22 01:01 mgood7123