jww*_*jww 9 gcc llvm clang visual-c++
我过去遇到过这个问题:LLVM定义__GNUC__,但它不能消耗GCC可以的程序.我在Windows上再次遇到它:LLVM定义_MSC_VER,但它不能使用VC++可以使用的相同程序.加重的事情(对我来说)是我们有LLVM Clang和Apple Clang的特殊代码路径(由于不同的版本方案而定义不同),我们必须与该工具对抗以使其使用它们.
我们如何告诉Clang不要假装成其他编译器?有没有开关或选项吗?
Clang文档讨论了不需要的MS行为,但他们没有说如何阻止它:
为了与使用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定义为内置类型.
Pet*_*des 10
__GNUC__并不特指 GCC。所有支持 GNU C 扩展的编译器都定义了它,包括 clang 和 ICC。
专门检测 GCC 的正常方法是排除其他“兼容”编译器
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
#define REAL_GCC __GNUC__ // probably
#endif
Run Code Online (Sandbox Code Playgroud)
Clang 前端定义了__clang__,但其他使用 LLVM 后端的前端也定义了__llvm__(例如 IBM XL C/C++ 版本 13.1.1 到 16.1)。最好只排除__clang__而不是__llvm__,这取决于您想排除它的原因。(例如,出于解析原因,而不是出于优化原因,例如__builtin_constant_p()在进行内联之前进行LLVM 评估,因此在内联函数的 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也出现在谷歌结果中,但不够完整.
您应该抱怨的是 GCC 本身并没有定义您可以检测到的特定于 GCC 的宏,只有它支持的 GNU 方言 C 版本。(GNU C 是一种语言,GCC 是该语言的编译器。不幸的是, GCC 的__GNUC_MINOR__/__GNUC_PATCHLEVEL__宏将两者混为一谈。)
铛定义__GNUC__/ __GNUC_MINOR__/__GNUC_PATCHLEVEL__根据gcc的版本,它声称具有完全兼容性。(可能仅适用于 GCC 文档保证可以工作的内容,而不适用于该版本或更高版本的 gcc 的内容。对于 GCC 本身,已记录=支持。被编译器接受并不意味着它得到支持并保证未来GCC 版本。这可能是 clang 声称支持某些 GNU C 版本的理由)。
例如,clang 7.0.1 将 GNUC/MINOR/PATCHLEVEL 定义为 4/2/1,即与 GCC 4.2.1 兼容
例如来自GCC 手册
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
…
/* Test for GCC > 3.2.0 */
#if GCC_VERSION > 30200
Run Code Online (Sandbox Code Playgroud)
如果您正在测试最近的 GCC 支持但最近的 clang 不支持的特定 GNU C 功能(还),您可能应该做类似的事情。
Mat*_*man 10
从版本 10 开始,clang 似乎有了一个选项。请参阅clang 的文档:
-fgnuc-版本=
该标志控制GNUC和相关宏的值。该标志不会启用或禁用 Clang 中实现的任何 GCC 扩展。将版本设置为零会导致 Clang 保留GNUC和其他 GNU 命名空间宏(例如GXX_WEAK)未定义。
因此,要禁用此行为,请-fgnuc-version=0在 clang 命令行上指定。
我们如何告诉 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++ 扩展未在 clang-on-Windows 中实现,因为它们的优先级不够高。如果它们是您的优先事项,请告诉我们。
| 归档时间: |
|
| 查看次数: |
1536 次 |
| 最近记录: |