我过去遇到过这个问题:LLVM定义__GNUC__
,但它不能使用GCC可以使用的程序。我在Windows上再次遇到它:LLVM定义_MSC_VER
,但它不能使用VC ++可以使用的相同程序。加重的事情(对我来说)是我们有LLVM Clang和Apple Clang的特殊代码路径(由于不同的版本方案而定义不同),我们必须使用该工具来使它们使用它们。
我们如何告诉Clang不要假装成其他编译器?有没有开关或选项来做?
Clang文档discuss the unwanted MS behavior,但他们没有说如何阻止它:
为了与使用MSVC编译的现有代码兼容,clang定义了_MSC_VER和_MSC_FULL_VER宏。这些默认值分别为1800和180000000,使得clang看起来像Visual C ++ 2013的早期版本。-fms-compatibility-version = flag会覆盖这些值。它接受虚线版本元组,例如19.00.23506。更改MSVC兼容性版本使clang表现得更像MSVC版本。例如,-fms-compatibility-version = 19将启用C ++ 14功能,并将char16_t和char32_t定义为内置类型。
答案 0 :(得分:1)
__GNUC__
并非专门针对GCC。。所有支持GNU C扩展的编译器都对其进行定义,包括clang和ICC。
检测GCC的正常方法是排除其他“兼容”编译器
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
#define REAL_GCC __GNUC__ // probably
#endif
Clang前端定义了__clang__
,但是其他使用LLVM后端的前端也定义了__llvm__
(例如,IBM XL C / C ++版本13.1.1至16.1)。最好排除__clang__
而不是__llvm__
,这取决于您要排除它的原因。 (例如,出于解析原因,与出于优化原因,例如LLVM在进行内联之前评估__builtin_constant_p()
一样,因此对内联函数的args无效。)
有关大型列表,另请参见https://sourceforge.net/p/predef/wiki/Compilers/。
https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html也出现在Google搜索结果中,但不够完整。
您应该抱怨的是,GCC本身并未定义您可以检测到的特定于GCC的宏,仅定义了它支持的C的GNU方言版本。 (不幸的是, GNU C是一种语言,GCC是该语言的编译器。不幸的是,GCC的__GNUC_MINOR__
/ __GNUC_PATCHLEVEL__
宏将这两个宏混合在一起。)
Clang根据声称完全兼容的gcc版本定义__GNUC__
/ __GNUC_MINOR__
/ __GNUC_PATCHLEVEL__
。 (可能仅适用于GCC文档保证可以使用的内容,不适用于与该版本或更高版本的gcc一起使用的内容。对于GCC本身,提供文档=支持。
被编译器接受并不意味着它会在将来的GCC版本中得到支持和保证。也许这就是clang声称支持某些GNU C版本的理由。
例如,clang 7.0.1将GNUC / MINOR / PATCHLEVEL定义为4/2/1,即与GCC 4.2.1兼容
例如来自the GCC manual
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
…
/* Test for GCC > 3.2.0 */
#if GCC_VERSION > 30200
如果您正在测试最新的GCC支持但尚未提供最新的clang(尚未)的特定GNU C功能,则您可能应该这样做。
答案 1 :(得分:1)
我也很惊讶地发现 Clang 定义了 _MSC_VER,但我所做的是做这样的事情:
#if defined(_MSC_VER) && !defined(__clang__)
// Real MSVC here
#elif defined(__clang__)
// Real CLANG here
答案 2 :(得分:0)
似乎clang现在对此有一个选择。参见the docs for clang:
-fgnuc-version =
此标志控制 GNUC 和相关宏的值。此标志不会启用或禁用在Clang中实现的任何GCC扩展。将版本设置为零会导致Clang留下未定义的 GNUC 和其他以GNU命名的宏,例如 GXX_WEAK 。
因此,要禁用此行为,请在clang命令行上指定-fgnuc-version=0
。
答案 3 :(得分:-1)
我们如何告诉Clang停止假装其他编译器?
我不知道该怎么做,也不知道它是否可行。为什么要这样做?我觉得您想这样做可以解决问题,但是也许有更好的解决方案。
[在Windows上,] LLVM定义_MSC_VER,
因为您可能正在使用标准库进行检查,以生成兼容的代码。
Clang在Windows上的目标不仅是生成在Windows上运行的独立代码,而且是可以与使用VC ++编译的库链接的代码。从源代码的角度来看,是使用clang还是VC ++进行编译应该没有区别。
如果您希望能够调用现有DLL,并且其头文件检查_MSC_VER
,则需要设置它是使用VC ++还是使用clang。
自撰写此问题以来,但是[Windows上的clang]不能使用VC ++可以使用的相同程序。
Clang在Windows上的功能已得到很大改进。现在有几个主要项目在Windows版本中使用clang。
如果找到VC ++可以接受但clang不能接受的正确程序,请提交错误报告。在大多数情况下,这可能是疏忽大意。有少量功能和VC ++扩展未在Windows的clang中实现,因为它们的优先级不够高。如果他们是您的重中之重,请告诉我们。