使用 Clang 与全局模板变量重复符号

2023-11-30

我有这三个文件

// foo.h
#pragma once

template <typename T> const T foo;

template <>
const int foo<int> = 1;
// a.cpp
#include "foo.h"

int main() {}
// b.cpp
#include "foo.h"

如果我在 Linux 上使用 GCC 7.5.0 构建它们,它可以正常工作:

$ g++ -std=c++17 a.cpp b.cpp -o out
$

然而,在 Mac 上使用 Apple Clang 12.0.0 时,会出现以下错误:

$ clang++ -std=c++17 a.cpp b.cpp -o out
duplicate symbol 'foo<int>' in:
    /var/folders/g5/8twmk1xj481_6btvppyw5j4h0000gp/T/a-62bdde.o
    /var/folders/g5/8twmk1xj481_6btvppyw5j4h0000gp/T/b-ea4997.o
ld: 1 duplicate symbol for architecture x86_64

这应该是一个错误,还是 Clang 中的一个错误?


RedFrog 的答案是正确的 - 这违反了单一定义规则(ODR),但它并没有真正解释why它违反了 ODR。在 C++ 全局中const变量有内部(static) 链接,这应该为每个编译单元生成一个单独的变量实例,因此不会违反 ODR。然而事实证明 that const不会导致template具有内部链接的变量:

在未声明为 extern 的非本地非易失性非模板 (C++14 起) 非内联 (C++17 起) 变量的声明上使用的 const 限定符赋予其内部链接。

有几种方法可以解决这个问题。

内部链接使用static

您可以使用static在模板变量上给他们内部联系:

在命名空间范围内声明的以下任何名称都具有内部链接:

声明为静态的变量、变量模板 (C++14 起)、函数或函数模板;

编辑:我不建议使用这种技术。如果您申请static对于声明和专业化,那么它在 Clang 中工作得很好,但 GCC(至少到目前为止)抱怨说

error: explicit template specialization cannot have a storage class

如果你设置static仅在声明上,然后它在 GCC 中编译,但使用 Clang 时会出现重复的符号错误。

内部链接使用namespace

将模板变量放在匿名名称空间中还可以为它们提供内部链接。

此外,在未命名命名空间或未命名命名空间内的命名空间中声明的所有名称,即使是显式声明为 extern 的名称,也具有内部链接。

使用禁用 ODRinline

这有点不同。声明的模板变量inline但不是static仍然有外部链接,但是允许有多个定义.

具有外部链接(例如未声明为静态)的内联函数或变量 (C++17 起) 具有以下附加属性:

  • 程序中可能存在多个内联函数或变量 (C++17 起) 的定义,只要每个定义出现在不同的翻译单元中并且(对于非静态内联函数和变量 (C++17 起) )) 所有定义都是相同的。例如,内联函数或内联变量 (C++17 起) 可以在多个源文件中 #include 的头文件中定义。
  • 它必须在每个翻译单元中声明为内联。
  • 它在每个翻译单元中具有相同的地址。

这意味着inline对于变量的行为就像inline对于功能。

如有疑问,inline可能是最好的选择。在我所做的非常简单的测试中,它们都产生相同的输出,即使在 -O0 时也是如此,但理论上inline保证程序中只有该变量的一个副本,因为它仍然具有外部链接,而其他方法则没有。或许。

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

使用 Clang 与全局模板变量重复符号 的相关文章

  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • 将参数传递给exe

    我有很多场景需要将参数传递给命令行执行程序 我在这个网站上看到了一些在某种程度上得到了回答 但到目前为止我还没有看到关于 powershell 如何处理参数的可靠的 通用的描述 两者都是通过 cmd 或启动进程传递的 这是一个让我烦恼的小例
  • 如何从输入数据集中删除非数字列?

    例如 如果我想考虑一种花的种类 花瓣数量 发芽时间和用户ID 用户ID那里会有一个连字符 所以在我的数据分析中 我不想使用它 我知道我可以对其进行硬编码 但我想让它在我输入任何数据集时 它会自动删除列non numeric inputs 编
  • (Angular 单元测试)如何在 Jasmin 中模拟输入属性?

    我目前正在尝试模拟 Angular 单元测试的输入属性 不幸的是 我无法进一步并反复收到以下错误消息 类型错误 无法读取未定义的属性 数据 我的 HTML 模板如下所示 div class container fluid div class
  • C++隐式转换序列中的三种转换

    页面位于http en cppreference com w cpp language implicit cast声明在隐式转换序列中最多可以完成三个转换序列 隐式转换序列按以下顺序包含以下内容 零个或一个标准转换序列 零个或一个用户定义的
  • LINQ to SQL SubmitChanges() 进度

    我正在使用 LINQ to SQL 将旧的 DBF 文件导入 MSSQL 我正在读取所有行并将它们添加到数据库中ctx MyTable InsertOnSubmit row 读取阶段完成后 我有大约 100 000 个待处理插入 ctx S
  • System.IO.File.ReadAllBytes 对于大于 2GB 的文件

    我有一个大文件 需要将其复制到内存中以供进一步处理 该软件对于小于 2GB 的文件运行良好 但一旦超过此限制 我就会得到一个例外 即 ReadAllBytes 仅支持小于 2GB 的文件 byte buffer System IO File
  • ClearCase:是否可以选择性地交付或变基?

    当将流A传递到流B时 是否可以只将选定的元素 准确地说是目录 从A传递到B 当从基线 B 变基流 A 时 是否可以仅将所选元素 准确地说是目录 从 B 变基到 A 使用 ClearCase UCM 您正在交付的是基线或活动 您正在重新设定的
  • HERE 地图 Android 集成,MISSING_LIBRARIES 错误

    我按照步骤操作https developer here com mobile sdks documentation android topics app simple android studio html 但我收到错误 无法初始化地图片段
  • 将文本字符 ☢ 在圆圈内垂直和水平居中 (CSS)

    我正在尝试将此文本字符 置于圆圈内 虽然 IE 10 显示文本垂直和水平居中 但 Chrome 和 Firefox 在顶部呈现过多的填充 任何想法如何解决这一问题 Flexbox 不是必须具备的 HTML div class tl icon
  • 更新 IPython/Jupyter 中使用的 R

    我想在 Jupyter Notebook 中使用 R 因此我通过 R Essentials 安装 请参阅 https www continuum io blog developer jupyter and conda r 安装的版本如下 R
  • 如何知道安装何时完成

    我正在创建一个应用程序来安装从服务器下载的应用程序 我想安装这些应用程序 下载文件后 我用于安装的方法的代码位于此处 public void Install String name prompts user to accept any in
  • 这段代码中 malloc 做了什么?

    你能解释一下下面的代码吗 str char malloc sizeof char num 1 什么是malloc在这里做什么 Why is num 1 used malloc是一个函数在堆上分配一块内存并返回一个pointer到它 它类似于
  • jQuery .append() 函数

    Why this mydiv append ul mydiv append li Hello li mydiv append ul alert mydiv html produces ul ul li Hello li and not ul
  • 理解类变量的继承

    我正在建造一个Challenge24SolverJava 中的类 逻辑本身起作用并找到预期的解决方案 具有任意数量的参数 无论如何 这部分项目正在按我的预期进行 这个问题来自于解决方案的表示问题 可以公平地说 我已经用 Python 完成了
  • 如果用户喜欢该页面,则signedRequest不会返回

    您好 我正在使用 facebook sdk php 版本 开发一个 fb 应用程序 但由于某种原因 signedRequest 没有返回我喜欢的变量以确定用户是否喜欢该页面 以下是signedrequest的print r Array id
  • 如何在 TypeScript 中定义一种类型,该类型可以具有除特定属性之外的任何属性?

    当编写像商店这样的字典的接口时 我想区分数据模型和商店中的项目 即id和模型 我想添加模型本身不使用字段的约束id在他们的界面中 但我不知道该怎么做 type Item
  • 将 Joomla 安装在子目录中

    你们中有些人可能知道 Wordpress 在设置中有一个选项 允许将站点安装在子目录中 同时将站点 URL 设为主域 它类似于 站点 url 和 Wordpress url 我正在 Joomla 中寻找类似的东西 我知道它没有内置选项 但如
  • Azure 存储队列和多个 WebJobs 实例:QueueTrigger 是否会在触发时设置消息租用时间?

    场景 生产者发送一条消息到Storage Queue 一个WebJobs在QueueTrigger上处理该消息 每条消息只能处理一次 可以有多个WebJob实例 我一直在谷歌搜索 根据我读到的内容 我需要编写处理消息的函数 使其具有幂等性
  • Webbrowser,检测是否安装了PDF阅读器?

    有没有办法检查用户是否安装了PDF阅读器 也许使用 ActiveX 组件 请你帮助我好吗 您可以使用以下命令检测已安装的插件window navigator plugins这将返回一个包含已安装插件详细信息的数组 但这不适用于 Intern
  • 使用 Clang 与全局模板变量重复符号

    我有这三个文件 foo h pragma once template