Live data from Hacker News

Recursive macros in C, demystified (once the ugly crying stops)

h4x0r.org

1–10 of 90 posts

Re: Recursive macros in C, demystified (once the ugly crying stops)

#3
Related: The Preprocessor Iceberg https://jadlevesque.github.io/PPMP-Iceberg/

There you can find a recursive macro expansion implementation (as a gcc hack) that fits on a slide:

  #2""3
  
  #define PRAGMA(...) _Pragma(#__VA_ARGS__)
  #define REVIVE(m) PRAGMA(push_macro(#m))PRAGMA(pop_macro(#m))
  #define DEC(n,...) (__VA_ARGS__)
  #define FX(f,x) REVIVE(FX) f x
  #define HOW_MANY_ARGS(...) REVIVE(HOW_MANY_ARGS) \
      __VA_OPT__(+1 FX(HOW_MANY_ARGS, DEC(__VA_ARGS__)))
  
  int main () {
      printf("%i", HOW_MANY_ARGS(1,2,3,4,5)); // 5
  }
It sounds like the one in the article works for more compilers, but there doesn't seem to be a copy-pasteable example anywhere to check for myself. Also, the "Our GitHub Org" link on the site just links to github.com.

Re: Recursive macros in C, demystified (once the ugly crying stops)

#4

Related: The Preprocessor Iceberg https://jadlevesque.github.io/PPMP-Iceberg/ There you can find a recursive macro expansion implementation (as a gcc hack) that fits on a slide: #2""3 #define PRAGMA(...) _Pragma(#__VA_ARGS__) #define REVIVE(m) PRAGMA(push_macro(#m))PRAGMA(pop_macro(#m)) #define DEC(n,...) (__VA_ARGS__) #define FX(f,x) REVIVE(FX) f x #define HOW_MANY_ARGS(...) REVIVE(HOW_MANY_ARGS) \ __VA_OPT__(+1 FX(…

Ask and you'll get: https://c.godbolt.org/z/rKsWT5E9T

It seems that MSVC doesn't like those macros, though.

Re: Recursive macros in C, demystified (once the ugly crying stops)

#6

Related: The Preprocessor Iceberg https://jadlevesque.github.io/PPMP-Iceberg/ There you can find a recursive macro expansion implementation (as a gcc hack) that fits on a slide: #2""3 #define PRAGMA(...) _Pragma(#__VA_ARGS__) #define REVIVE(m) PRAGMA(push_macro(#m))PRAGMA(pop_macro(#m)) #define DEC(n,...) (__VA_ARGS__) #define FX(f,x) REVIVE(FX) f x #define HOW_MANY_ARGS(...) REVIVE(HOW_MANY_ARGS) \ __VA_OPT__(+1 FX(…

Author of the article here.

Absolutely, the code box under the ascii art is a complete implementation, just paste that in a C file, and then use `H4X0R_VA_COUNT(...)`.

Or, you could follow the link the my typed variadic arguments article (from which this post forked off). The repo there is: https://codeberg.org/h4x0r/vargs

Re: Recursive macros in C, demystified (once the ugly crying stops)

#7
The behavior of C macros is actually described by a piece of pseudocode from Dave Prosser and it is not in the standard:

* https://www.spinellis.gr/blog/20060626/

* https://www.spinellis.gr/pubs/jrnl/2006-DDJ-Finessing/html/S...

* https://gcc.gnu.org/legacy-ml/gcc-prs/2001-q1/msg00495.html

Re: Recursive macros in C, demystified (once the ugly crying stops)

#8
post #6

Related: The Preprocessor Iceberg https://jadlevesque.github.io/PPMP-Iceberg/ There you can find a recursive macro expansion implementation (as a gcc hack) that fits on a slide: #2""3 #define PRAGMA(...) _Pragma(#__VA_ARGS__) #define REVIVE(m) PRAGMA(push_macro(#m))PRAGMA(pop_macro(#m)) #define DEC(n,...) (__VA_ARGS__) #define FX(f,x) REVIVE(FX) f x #define HOW_MANY_ARGS(...) REVIVE(HOW_MANY_ARGS) \ __VA_OPT__(+1 FX(…

Author of the article here. Absolutely, the code box under the ascii art is a complete implementation, just paste that in a C file, and then use `H4X0R_VA_COUNT(...)`. Or, you could follow the link the my typed variadic arguments article (from which this post forked off). The repo there is: https://codeberg.org/h4x0r/vargs

And yes, GCC extensions are often going to be adopted in clang, but generally not the broader world of C and C++ compilers. Everything in my article conforms to the standard.

Re: Recursive macros in C, demystified (once the ugly crying stops)

#9

Can I use this technique to expand MACRO(a,b,c,…) into something like F(a,b,c…); G(a,b,c…)?

That's just:

``` #define MACRO(...) F(__VA_ARGS__); G(__VA_ARGS__) ```

The technique in the article is more often used to type check the individual parameters, or wrap a function call around them individually, etc.

Post reply on HN