C 严格化的错误使用

C 严格化的错误使用,c,gcc,macros,c-preprocessor,stringification,C,Gcc,Macros,C Preprocessor,Stringification,给定以下代码: #define MY_STRINGIFY_MACRO(...) #__VA_ARGS__ #define PORT_MAC(portNum) port: portNum #define LOG_MACRO(...) printf( MY_STRINGIFY_MACRO(__VA_ARGS__) ) void func(int portNum) { LOG_MACRO( PORT_MAC(portNum) ); /* In a more general w

给定以下代码:

#define MY_STRINGIFY_MACRO(...) #__VA_ARGS__

#define PORT_MAC(portNum) port: portNum

#define LOG_MACRO(...)
     printf( MY_STRINGIFY_MACRO(__VA_ARGS__) ) 

void func(int portNum)
{
    LOG_MACRO( PORT_MAC(portNum) ); /* In a more general way I would use this macro as LOG_MACRO( PORT_MAC(portNum), PORT_MAC(portNum1) ... ); to get output of " port: 2, port: 3 ... "*/
}
使用端口号调用
func()
时,例如
2
,输出为:

 port: portNum
而不是

 port: 2
如果我按以下方式使用宏:

 LOG_MACRO( PORT_MAC(2) );
然后我得到所需的输出:

 port: 2     

如何修复代码,使其能够处理这两种情况,并且输出始终包含
portNum
值?

您似乎对编译时和运行时感到困惑

宏在编译时运行(在对代码执行任何其他操作之前)。这就是替换发生的时候。此时,CPP(C预处理器)只考虑文本。它看不到任何其他东西(甚至不希望它是有效的C代码!)。然后编译代码,得到二进制文件(
a.out


此时,没有执行任何代码。没有调用任何函数。只有在启动程序时(
$./a.out
)才会调用函数并传递参数。你想做的是不可能的。您唯一的选择是在运行时替换文本。

您唯一的选择是在运行时替换文本
您能解释一下吗?您有一个
常量char*
(您正在传递到
printf
)。您需要“手动”替换该值(之前不要忘记复制字符串。修改
const char*
可能会导致segfault)。另一种方法是调用
LOG\u宏(PORT\u MAC(%d),portNum)
。但这意味着
LOG\u宏
不允许使用
\uuuu VA\u ARGS\uuu
(因为您需要将
\uuu VA\u ARGS\uuu
传递到printf)