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

sop*_*sop 30 c c++ macros

我知道我的问题类似于这一个或者这个问题,但是我发现它实际上并不相同,而且,第二个问题没有得到答案,我决定问在添加预处理程序指令时是否正确一个类似函数的宏被调用?

在我的情况下,我有一个类似函数的宏:

#define FUNC_MACRO(a, b)  // do something with the variables
Run Code Online (Sandbox Code Playgroud)

如果定义了其他一些宏,我会在代码中的某个地方调用它:

// ...
FUNC_MACRO(aVal
#ifdef ANOTHER_MACRO
                + offset
#endif // ANOTHER_MACRO
           , bVal);
// ...
Run Code Online (Sandbox Code Playgroud)

我在我的机器上测试过(linux,用gcc 4.8)并且它工作正常(有和没有预处理器指令,有和没有定义ANOTHER_MACRO),但这样做是否安全?

我从第一个类似问题的答案中读到了16.3/9段落,但我的情况也是如此吗?

R..*_*R.. 45

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

如果参数列表中存在预处理标记序列,否则这些标记将充当预处理指令,则行为未定义.

这样做确实是错的.

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

更新:PJTraill在评论中询问了在宏扩展中使用预处理程序指令会"误导或无意义"的情况.这是一个显而易见的问题:

    foo(a, b,
#ifdef BAR
        c);
#else
        d);
#endif
Run Code Online (Sandbox Code Playgroud)

我不确定语言是否可以指定宏扩展中的平衡预处理器条件是可以的,但我认为你也会遇到问题,它们的处理顺序也有歧义.

  • 这很好知道,但考虑到微软需要"调整"方法以跨ASCII和Unicode或"正常"和"安全"等工作,我希望他们的编译器实际上支持这一点.恕我直言,一个宏的重点是你不应该知道它的宏. (2认同)
  • 这似乎是结论性的,但乍一看似乎可以对代码进行直观,合理的解释-如果出现误导或毫无意义的情况,您是否可以激发语言标准? (2认同)

Tob*_*oby 20

请执行以下操作?

#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif
Run Code Online (Sandbox Code Playgroud)

编辑:解决评论引起的关注; 我不知道OP的方法是否特别错误(我认为其他答案涵盖了这一点).然而,简洁性和清晰度是用C编码时非常重要的两个方面.

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

  • @ Peregring-lk你错了.[如何回答](http://stackoverflow.com/help/how-to-answer)明确欢迎提供替代解决方案的答案:"答案可能是'不要那样做',但它也应该包括'尝试'而不是"." 这不是最好的答案,因为一个好的答案也可以解释为什么它与替代方案一样糟糕,但它是这个问题的合理答案. (5认同)
  • 这是一个解决方案,而不是答案.确实有效的事情,避免另一个可能没有,但我们真的不知道.但他肯定想知道这一点. (2认同)