【发布时间】:2015-10-08 14:18:23
【问题描述】:
C 有__STDC__,但似乎没有识别某些扩展 C++ 方言的标准方法。因此,对于我使用的可移植代码
#define __is_extended \
((__GNUG__ &&!__STRICT_ANSI__) || \
(_MSC_VER && _MSC_EXTENSIONS && __cplusplus) || \
(__IBMCPP__ && __EXTENDED__))
到目前为止,这适用于 gcc、XLC 和 Visual C++。
我们必须针对每个编译器进行 ISO/ANSI 一致性测试,对吗?如果是这样,您能否为其他已被证明有效的编译器提出建议?
编辑:由于对此类测试的赞成和反对进行了很多讨论,所以这里有一个真实的例子。假设有一些头文件 stuff.h 在多个项目中与多个编译器一起广泛使用。 stuff.h 使用一些特定于编译器的 vsnprintf(在 C++11 之前未标准化)、一些 copy_if<>(在 C++98 中使用 they somehow missed)、自己的互斥锁以及其他别的。在实现一个干净的 C++11 变体时,您将旧的(但受信任的)实现包装在一些 #if __is_extended 中(更好的是:__is_idosyncratic 或 !__is_ANSI_C11)。新的 C++11 落后于 #else。当仍编译为 C++0x 或 C++98 的翻译单元包含 stuff.h 时,没有任何变化。没有编译错误,运行时没有不同的行为。 C++11 仍然是实验性的。代码可以安全地提交到主分支,同事可以研究它,从中学习并在其组件中应用技术。
【问题讨论】:
-
你从这样的宏中得到了什么?非标准扩展确实因编译器而异,因此您只知道 一些 扩展被激活。
-
我不明白这个问题。你能举一个具体的例子来说明你会用
__is_extended的结果做什么吗? -
确保某些翻译单元不能使用一些语言扩展。启用像
#if __is_extended #error this is portable code #endif这样的编译时断言,或者像#define __is_ANSI_CPP11 (__cplusplus == 201103L && !__is_extended)这样的宏。 -
@AndreasSpindler:但这比简单地使用严格一致性标志调用编译器更好吗?例如,如果您使用
/Ze标志,将定义_MSC_EXTENSIONS。这个问题的解决方案不是使用/Ze,而是使用/Za。为什么要先在编译器中启用扩展,然后将自己的编译器配置视为错误? -
定义上述标记会使您的程序在标准下格式不正确。我也看不出你会如何有效地使用它。
标签: c++ c-preprocessor gnu ansi xlc