如何告诉 Clang 不要冒充其他编译器?

2024-02-29

我过去遇到过这个问题:LLVM 定义__GNUC__ https://www.google.com/search?q=%22__GNUC__%22+LLVM+bug,但它不能使用 GCC 可以使用的程序。我在 Windows 上再次遇到它:LLVM 定义_MSC_VER https://www.google.com/search?q=LLVM+%22_MSC_VER%22+bug,但它不能使用 VC++ 可以使用的相同程序。对我来说,令人恼火的是我们有专门的 LLVM Clang 和 Apple Clang 的代码路径(由于不同的版本方案而有不同的定义),我们必须与该工具斗争才能让它使用它们。

我们如何告诉 Clang 不要冒充其他编译器?是否有一个开关或选项可以做到这一点?


Clang 文档讨论不需要的 MS 行为 http://clang.llvm.org/docs/UsersManual.html,但他们没有说如何阻止它:

为了与使用 MSVC 编译的现有代码兼容,clang 定义了 _MSC_VER 和 _MSC_FULL_VER 宏。这些默认值分别为 1800 和 180000000,使 clang 看起来像 Visual C++ 2013 的早期版本。 -fms-compatibility-version= 标志会覆盖这些值。它接受点分版本元组,例如 19.00.23506。更改 MSVC 兼容版本使 clang 的行为更像该版本的 MSVC。例如,-fms-compatibility-version=19 将启用 C++14 功能并将 char16_t 和 char32_t 定义为内置类型。


__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()在进行内联之前,因此它在内联函数的参数上毫无用处。)

也可以看看https://sourceforge.net/p/predef/wiki/Compilers/ 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 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's __GNUC_MINOR__ / __GNUC_PATCHLEVEL__不幸的是,宏将两者混为一谈。)

Clang 定义__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兼容

例如从海湾合作委员会手册 https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

#define GCC_VERSION (__GNUC__ * 10000 \
                     + __GNUC_MINOR__ * 100 \
                     + __GNUC_PATCHLEVEL__)
…
/* Test for GCC > 3.2.0 */
#if GCC_VERSION > 30200

如果您正在测试最近的 GCC 支持但最近的 clang 还不支持的特定 GNU C 功能,那么您可能应该这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何告诉 Clang 不要冒充其他编译器? 的相关文章

随机推荐

  • FirebaseCore 词法或预处理器问题

    所以我在使用 firebase 编译我的项目时遇到了问题 这个问题是在我更新所有 firebase pod 后开始的 自从我更新了 pod 后 我就一直收到此错误 词法或预处理器问题 然后当我转到错误是什么时 它说这个 找不到 Google
  • 对 kafka 消费者进行负载测试

    我试图弄清楚如何对卡夫卡消费者进行负载测试 在我的应用程序中 消费者从 kafka 读取消息并做了很多工作 其中大部分是在数据库中写入内容 由于这对我的团队来说是一个重要的过程 因此我希望能够对消费者进行负载测试 并能够获得一些有关消费情况
  • 将多行合并为一行以替换列中的空值

    如何将多行合并为一行 以便一行中的某些列替换要合并的另一行中相同列中的空值 这是我所拥有的和我想要实现的目标的一个例子 查询是 SELECT Drug Name DefaultVendor Name Drug Strength Catalo
  • AndroidrelativeLayoutalignTop不起作用

    我正在尝试在RelativeLayout 中使用alignTop 属性 以便将文本设置在个人资料图片的右侧 与图片的顶部对齐 这是我的布局
  • 将文本添加到 DataGridView 行标题

    C 是否允许将字符串添加到 DataGridView 中的 RowHeader 如果是的话 是如何实现的呢 我正在编写一个 Windows 窗体来显示今年迄今为止的客户付款数据 ColumnHeaders 显示一月 二月 三月等 而不是有一
  • 如何避免 JavaScript 中的短路求值?

    我需要执行两边 声明 但如果第一部分返回 则不会发生这种情况false 例子 function doSomething x console log x function checkSomething x var not1 x 1 if no
  • 如何保护客户端/服务器套接字通信的安全

    假设客户端和服务器应用程序在不同的计算机上运行 Today Server will receive the request and cast it as needed ProxyResponse message ProxyResponse
  • docker buildx“执行用户进程导致:执行格式错误”

    我正在尝试交叉编译一个 Rust 应用程序以在我的树莓派集群上运行 我看到 docker 的 buildx 应该能够使这成为可能 我现在有一个最小的 dockerfile 如下所示 FROM rust RUN apt get update
  • 在本地工作的 R 脚本不适用于shinyapp.io

    我正在尝试组装一个 R Shiny 应用程序 至少在最初 它可以绘制日期数据的直方图 我让它在 RStudio 的本地系统上工作得很好 但在闪亮的应用程序 io 中它不起作用 目前 该应用程序非常简单 用户界面实际上没有做任何事情 数据只是
  • Jupyter 上 Sparkcollect() 的 IllegalArgumentException

    我设置了 Jupyter 4 3 0 Python 3 6 3 Anaconda 和 PySpark 2 2 1 以下示例在通过 Jupyter 运行时将失败 sc SparkContext getOrCreate rdd sc paral
  • 如何获取两个列表之间的所有唯一分配

    我有两个列表 每个列表都可以包含重复的值 但任何值只能出现在这两个列表之一 或没有 中 A 0 1 B 2 3 我想获得这两个列表之间的所有唯一映射 assignment A B 0 2 1 3 0 3 1 2 我知道这可以例如使用 ite
  • 如何解决 MSCV 中 Boost 文件系统库的 LNK1104 错误?

    我无法将我的项目链接到 Microsoft Visual C 2008 Express Edition 中的 Boost 版本 1 37 0 文件系统 lib 文件 文件系统库是not仅标头库 我一直在关注Windows 入门 http w
  • 如何处理pygame中不同组件的时间

    我正在制作一个 pygame 游戏 人们可以从商店购买炸弹 玩家还可以投下购买的炸弹数量 我需要一种方法让每个炸弹在投下 3 秒后消失 在下面的代码中 我只能投下炸弹 但是我尝试了各种方法但失败了 import pygame import
  • 使用 .NET Core 的 Linux/Unix 上的文件权限

    我正在尝试学习如何使用 NET Core 在 Linux Unix 上设置文件权限 我已经在这里发现了一个问题 它指出了 System IO FileSystem 的方向 但我似乎找不到任何有关如何使用它的文档 简而言之 我想从仅在 Lin
  • 在 React Native 应用程序中发送应用程序邀请

    在 facebook iOS SDK 中 有一个名为 App Invites 的模块 允许将您的应用程序的邀请发送给您的朋友 https developers facebook com docs ios https developers f
  • sstream 重新声明并出现公共访问编译器错误

    我在使用 gcc5 4 0 在大型项目上运行 make 时遇到了此错误 usr include c 5 sstream 300 14 error xfer bufptrs redeclared with public access stru
  • gensim 的 get_document_topics 方法返回的概率加起来不等于 1

    有时它返回所有主题的概率并且一切都很好 但有时它只返回几个主题的概率并且它们加起来不等于一 似乎这取决于文档 一般来说 当它返回很少的主题时 概率加起来大约为 80 那么它只返回最相关的主题吗 有没有办法强制它返回所有概率 也许我遗漏了一些
  • \t 只被视为 1 个字符吗?

    我试图用 do while 和子字符串来做一些基本逻辑 如下所示 bool foundFirstTaskname false int startCounter 0 do var checkEveryTwo name Substring st
  • 这是内置的绘图吗?

    In 这个链接的图像 http snpent com images button gif 我在很多应用程序中经常看到右侧的按钮 在我的 Moto Droid 上 它在设置应用程序中广泛使用 它还用作默认的 AlertDialog 图标 我可
  • 如何告诉 Clang 不要冒充其他编译器?

    我过去遇到过这个问题 LLVM 定义 GNUC https www google com search q 22 GNUC 22 LLVM bug 但它不能使用 GCC 可以使用的程序 我在 Windows 上再次遇到它 LLVM 定义 M