在类函数宏中添加预处理器指令是错误的吗?

Is it wrong to add preprocessor directives in a function-like macro?

本文关键字:错误 指令 处理器 类函数 添加 预处理      更新时间:2023-10-16

我知道我的问题类似于这个或这个,但我发现它不是真的一样,更多的是,第二个没有接受的答案,我决定问是否正确添加预处理器指令时,类函数的宏被调用?

在我的例子中,我有一个类似函数的宏:
#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段,但对我的情况也是如此吗?

C语言将此作为6.10.3宏替换中的未定义行为,¶11:

如果参数列表中有预处理令牌序列,否则将充当预处理指令,则该行为是未定义的。

所以这样做确实是错误的。

GCC和其他流行的编译器可能无法捕捉到它,这可能是该语言的许多用户不知道的原因。当我的一些代码无法在PCC上编译时,我遇到了这个问题(并立即修复了代码中的错误)。

Update: PJTraill在评论中询问在宏扩展中使用预处理器指令会"误导或无意义"的情况。下面是一个很明显的例子:

    foo(a, b,
#ifdef BAR
        c);
#else
        d);
#endif

我不确定在宏展开中指定平衡的预处理器条件是否合理,但我认为您也会遇到问题,在处理它们的顺序中存在歧义。

做以下事情?

#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif

EDIT:处理评论引起的关注;我不知道OP的方法是否特别错误(我认为其他答案涵盖了这一点)。然而,简洁和清晰是用c编程时非常重要的两个方面。

因此,我更愿意找到更好的方法来实现OP似乎正在尝试的,通过稍微重新思考我上面提供的情况。我猜OP可能使用了一个琐碎的例子,但我通常发现大多数C的情况下,如果事情变得过于复杂或试图做一些事情似乎不像语言应该允许的,那么有更好的方法来实现所需的东西。