我知道我的问题类似于this one或this one,但我发现它不是真的相同,而且更多的是,第二个问题没有得到答案,我决定问一下如果在调用类似函数的宏时添加预处理程序指令是否正确?
在我的情况下,我有一个类似函数的宏:
#define FUNC_MACRO(a, b) // do something with the variables
在代码中的某个地方,如果定义了其他宏,我会将其称为具体差异:
// ...
FUNC_MACRO(aVal
#ifdef ANOTHER_MACRO
+ offset
#endif // ANOTHER_MACRO
, bVal);
// ...
我在我的机器上测试过(linux,用gcc 4.8)并且它工作正常(有和没有预处理器指令,有和没有定义ANOTHER_MACRO),但这样做是否安全?
我从第一个类似问题的答案中读到了16.3 / 9段落,但我的情况也是如此吗?
答案 0 :(得分:45)
C语言将此作为未定义的行为留在 6.10.3宏替换中,¶11:
如果参数列表中存在预处理标记序列,否则这些标记将作为预处理指令,则行为未定义。
这样做确实是错的。
GCC和其他流行的编译可能无法捕获它,这可能是许多该语言用户不知道的原因。当我的一些代码无法在PCC上编译时(我及时修复了我的代码中的错误),我遇到了这个问题。
更新:PJTraill在评论中询问了在宏扩展中使用预处理程序指令会“误导或毫无意义”的情况。这是一个显而易见的问题:
foo(a, b,
#ifdef BAR
c);
#else
d);
#endif
我不确定该语言是否可以指定宏扩展中的平衡预处理器条件是可以的,但我认为你也会遇到歧义按照处理顺序排列。
答案 1 :(得分:20)
请执行以下操作?
#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif
编辑:解决评论提出的问题;我不知道OP的方法是否具体错误(我认为其他答案涵盖了这一点)。然而,简洁性和清晰度是用C编码时非常重要的两个方面。
因此,我更愿意找到更好的方法来实现OP似乎正在尝试的东西,稍微重新考虑我上面提到的情况。我想OP可能已经使用了一个简单的例子但我通常发现在大多数C情况下,如果某些东西变得过于复杂或试图做某事似乎不是语言应该允许的话,那么有更好的方法来实现所需要的