M4宏嵌套pushdef时代码生成不符合预期问题咨询
Let's break down what's going wrong and how to fix it, step by step.
The Root Cause
The main issue throwing off your output is missing spacing between method declarations in the __for_each macro. When the recursive call executes, it directly appends the next method line without any whitespace, leading to cramped output like virtual int ma() = 0;virtual void mb() = 0; instead of your properly spaced expected result.
There's also a minor robustness tweak we can make to the recursive argument handling, but the spacing mismatch is the primary reason your output doesn't match expectations.
Fixed Macro Code
Here's the adjusted version that produces exactly what you want:
define(`__for_each', `ifelse(`$#', `1', `', `$#', `2', `$1(`$2')', `$1(`$2') __for_each(`$1', shift(shift($@)))')')dnl define(`__method_decl', `virtual $2 $1() = 0;') define(`__expose_method', `pushdef(`method', `__method_decl')$1 popdef(`method')')dnl define(`interface', ``struct' $1 { __for_each(`__expose_method', shift($@)) };')dnl interface(iface, method(ma, int), method(mb, void))
Key Fixes:
- Added spacing in
__for_each: We inserted a space between$1($2')and the recursive__for_each` call. This ensures each method declaration is separated by a space, matching your desired format. - Preserved your core logic: The
pushdef/popdefpattern still correctly mapsmethodto__method_decltemporarily, andshift(shift($@))properly iterates through remaining method arguments without breaking the recursion.
Testing the Fix
Run the adjusted code with m4 your-file.m4, and you'll get the exact output you expected:
struct iface { virtual int ma() = 0; virtual void mb() = 0; };
Extra Notes
- The
dnlsuffix on macro definitions is critical—it suppresses unwanted newline characters in the output, keeping your generated code clean and compact. - The
pushdef/popdefapproach is smart here because it only redefinesmethodinside the scope of__expose_method, avoiding any global macro conflicts that could break other parts of your code.
内容的提问来源于stack exchange,提问作者Deedee Megadoodoo

