Live data from Hacker News

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

h4x0r.org

11–20 of 90 posts

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

#12

Is this a DoS risk - code that sends your build chain into an infinite loop?

No. Other modern languages have strong compile-time execution capabilities, including Zig, Rust and C++. And my understanding is that C is looking to move in that direction, though as with C++, macros will not go away.

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

#13
post #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.

Ok. How about into F(a,”a”);F(b,”b”);etc.

The problem being automating enums and their names in one call. Like MACRO(a,b,c) and getting a map from a to “a”.

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

#15
post #9

Earlier quoted context omitted.

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.

Ok. How about into F(a,”a”);F(b,”b”);etc. The problem being automating enums and their names in one call. Like MACRO(a,b,c) and getting a map from a to “a”.

100%, that's definitely easy to do once you understand the technique.

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

#16

Is this a DoS risk - code that sends your build chain into an infinite loop?

Without any specific implementation of a constraint it certainly can happen, although I'm not totally sure that it's something to be concerned about in terms of a DOS as much as a nuisance when writing code with a bug in it; if you're including malicious code, there's probably much worse things it could do if it actually builds properly instead of just spinning indefinitely.

Rust's macros are recursive intentionally, and the compiler implements a recursion limit that IIRC defaults to 64, at which point it will error out and mention that you need to increase it with an attribute in the code if you need it to be higher. This isn't just for macros though, as I've seen it get triggered before with the compiler attempting to resolve deeply nested generics, so it seems plausible to me that C compilers might already have some sort of internal check for this. At the very least, C++ templates certainly can get pretty deeply nested, and given that the major C compilers are pretty closely related to their C++ counterparts, maybe this is something that exists in the shared part of the compiler logic.

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

#17

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.

Works with MSVC if you add /Zc:preprocessor (to get a standard compliant preprocessor instead of the legacy one).

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

#18
post #15

Earlier quoted context omitted.

Ok. How about into F(a,”a”);F(b,”b”);etc. The problem being automating enums and their names in one call. Like MACRO(a,b,c) and getting a map from a to “a”.

100%, that's definitely easy to do once you understand the technique.

Please?

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

#19
I wonder if the author is aware of the __VA_TAIL__ proposal[1], it covered similar grounds and IMO very well thought out, but unfortunately not accepted into C2Y (judging from committee meeting minutes).

[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3307.htm

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

#20
post #19

I wonder if the author is aware of the __VA_TAIL__ proposal[1], it covered similar grounds and IMO very well thought out, but unfortunately not accepted into C2Y (judging from committee meeting minutes). [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3307.htm

Yes, I know that it was not accepted, but do not have any color on why not. It's well thought out; but I do not think the semantics are self-evident to the average C programmer who already finds the preprocessor inscrutable.
Post reply on HN