G++ 为未使用的模板特化生成代码?

2023-12-31

在我正在处理的项目的一些序列化代码中,我有一个类型,其大小取决于编译器。为了解决这个问题,我决定使用模板专业化,效果很好。一切都在编译时解决。代码看起来有点像这样(不是真正的代码,只是一个例子):

template <int size>
void
special_function()
{
     std::cout << "Called without specialization: " << size << std::endl;
}

template <>
void
special_function<4>()
{
     std::cout << "dword" << std::endl;
}

template <>
void
special_function<8>()
{
     std::cout << "qword" << std::endl;
}

int
main()
{
     special_function<sizeof(int)>();
     return 0;
}

在我的32位系统上,执行上述程序输出dword,正如预期的那样。但这样做的全部意义在于这样做而不仅仅是这样做if (sizeof(int) == 4) { ... } else if ...是我希望编译器只会为适当的函数生成代码。自从special_function<4>是该程序中唯一调用的一个,我希望它是编译器(在本例中为 gcc 4.1.2,在 x86 Linux 上)生成的唯一一个。

但这不是观察到的行为。

虽然它确实有效,但每个模板专业化的代码都会生成,尽管从未使用过。但是,不会生成通用定义。

我应该指出,这是一步编译,而不是编译成中间目标文件,然后是链接。在这种情况下,将死代码删除推迟到链接阶段似乎很自然,而且我知道链接器并不总是非常擅长于此。

有谁知道发生了什么事吗?我在这里缺少模板专业化的微妙之处吗?天知道C++ 的问题在于细节。

编辑:既然已经提到过,这种行为会发生在 -O3 和 -Os 上。

EDIT2:下面的 Rob 建议将函数放在匿名名称空间中。这样做并使用任何级别的优化进行编译确实可以删除死代码,这很好。但我很好奇,所以我尝试对以下程序执行相同的操作:

namespace {
void foo() { std::cout << "Foo!" << std::endl; }
void bar() { std::cout << "Bar!" << std::endl; }
}

int
main()
{
       foo();
       return 0;
}

这里的想法是看看 Rob 的解决方案是否实际上与模板专业化相关。事实证明,上面打开优化编译的代码忽略了未使用的定义bar()来自可执行文件。因此,虽然他的答案解决了我眼前的问题,但它并没有解释为什么根本没有使用的模板专业化会被编译。

有谁知道标准中的相关片段可以解释这一点?我一直认为模板仅在使用时生成,但对于完全专业化来说可能并非如此......


您的示例中的模板专业化是具有外部链接的函数。编译器无法知道它们不会被另一个翻译单元调用。

在我的 g++ 4.7.2 Ubuntu 系统上,将模板放入匿名名称空间并使用-O3防止生成未使用的函数。

同样,声明函数模板static达到了预期的效果。

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

G++ 为未使用的模板特化生成代码? 的相关文章

  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include
  • 以编程方式使用自定义元素创建网格

    我正在尝试以编程方式创建一个网格 并将自定义控件作为子项附加到网格中 作为 2x2 矩阵中的第 0 行第 0 列 为了让事情变得更棘手 我使用了 MVVM 设计模式 下面是一些代码可以帮助大家理解这个想法 应用程序 xaml cs base

随机推荐

  • 从 php 脚本制作可点击的文本

    我下面有一个 php 脚本 这会产生以下输出 美联社活动报道 Configure Maintain Service Configure Monitor SNC Configure Monitor Service Report ON SNC
  • 如何更改禁用的 ttk 按钮的前景色?

    当我禁用按钮时 颜色自动变为黑色 这是代码 from tkinter import from tkinter import ttk root Tk style ttk Style style configure TButton foregr
  • 如何组织 ASP.NET app_code 文件夹? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 Typescript 中定义泛型函数类型;两种类似的方式?

    我正在尝试在 Typescript 中定义一些通用函数类型 似乎有两种类似的方法可以做到这一点 而且它们都有效 然而第二种形式 见下文ConcatY 似乎不那么灵活 或者至少我不知道如何指示函数采用具有特定参数类型的其中之一 有没有办法定义
  • 使用 Mocha 和 Istanbul 时从覆盖范围中排除文件

    使用 mocha 和 instanbul 时 如何从覆盖率报告中排除文件夹和文件 按路径 我想通过配置排除而不是 istanbul ignore next 在每个文件中 Jenkins使用生成的报告 Thanks 您可以使用以下命令忽略与特
  • 异步显示对话框

    我正在使用 async await 从数据库异步加载数据 在加载过程中 我想弹出一个加载表单 它只是一个简单的表单 带有运行进度条以指示有一个正在运行的进程 加载数据后 该对话框将自动关闭 我怎样才能做到这一点 下面是我当前的代码 prot
  • 如何在 Lumen 中使用身份验证进行用户登录?为什么我在启动时看到“未经授权”?

    我有一个无法加载 显示的登录页面 用户名 密码输入 相反 启动应用程序时 显示的只是 未经授权 这是来自命令Authenticate php我已将其进一步包含在下面 My routes php app gt get PageControll
  • 获取前台应用程序图标转换为base64

    我正在尝试获取前台应用程序图标并将其转换为 base64 我可以获取前台应用程序的名称 但无法获取图标 当我对其进行编码时 我得到一个字符串 但它不是图标 我不确定我的错误在哪里 这是我的代码 public class RunningSer
  • 在 WCF REST 序列化之前将 System.IO.Stream 转换为数据传输对象?

    这个问题建立在之前的问题的基础上 尽管偏离主题 我昨天问过 https stackoverflow com questions 4889439 getting a type specific response from a wcf rest
  • postgresql中的round函数究竟是如何工作的?

    postgresql中的round函数实际上是如何工作的 下面的查询展示了奇怪的行为 SQL DEMO http rextester com IHQ94614 select val Round x val NUMERIC as NUMERI
  • 带有文件 I/O 和数组列表的 JTable

    在我的程序中 用户输入单词及其相应的定义 该用户定义对象的一个 示例是 面容 人脸 用户的单词存储在一个与文件 I O 一起使用的数组列表中 但是 每次我调用 prepareTable 方法时 程序 将文本文件中找到的单词的重复项添加到数组
  • URL 的正则表达式

    下面发布的正则表达式用于获取 URL 包括以下格式的 URL example com 但是 我希望它只获取具有www or http https等在前面 换句话说 它应该拾起www example com 它不应该拾取example com
  • TreeMap 中的键返回 null

    所以我有一个非常奇怪的错误 当我最初使用 keySet 迭代大型 TreeMap 的前 10 个键时 我偶然发现了它 其中一个键返回 null 据我的理解 这应该是不可能的 所以我写了下面的测试代码 int i 0 for Map Entr
  • 如何将双引号字符串与转义双引号字符匹配?

    我需要一个 Perl 正则表达式来匹配字符串 我假设只有双引号字符串 是文字引号字符 而不是字符串的结尾 而 是文字反斜杠字符 不应转义引号字符 如果不清楚 有些例子 string is 1 character long contains
  • Datastax cassandra 存在性能问题

    我已经在两台独立的机器上安装了 datastax Cassandra 一台具有 16GB RAM 另一台具有 32GB RAM 并采用大部分默认配置 我创建了一个包含大约 700 列的表 当我尝试使用 java 插入记录时 它每 30 秒能
  • ASP.Net MVC 操作结果是什么?

    是否有所有 ASP Net MVC 操作结果及其用途的列表 我一直忙于使用 ActionResult 来处理几乎所有事情 但我知道这是不正确的 我应该使用更具体的操作结果 我用谷歌搜索过这个但找不到列表 我们刚刚购买了 Wrox 的书 但距
  • 在 XAML 中访问 c​​ontroltemplate 中元素的属性

    我想使用由图像和标签组成的模板化 ComboBoxItems 如果我将模板分配给 ComboBoxItem 我可以以某种方式设置图像的源属性吗 目标是对不同的 ComboBoxItems 使用相同的模板 但每个 Item 中使用不同的图片
  • 使用 Google Drive Api v2 选择特定字段

    我有一个错误 Google Apis Requests RequestErrorInvalid field selection filesize 400 Errors Message Invalid field selection file
  • 如何检测变量值何时发生变化

    如何轻松检测变量值何时发生变化 我希望每当指定的变量更改值时 程序的执行就会在调试器上中断 现在我正在使用 Eclipse 的调试器 对于类或实例变量 右键单击大纲视图中的变量 选择 切换观察点 然后 在断点视图中 您可以右键单击生成的结果
  • G++ 为未使用的模板特化生成代码?

    在我正在处理的项目的一些序列化代码中 我有一个类型 其大小取决于编译器 为了解决这个问题 我决定使用模板专业化 效果很好 一切都在编译时解决 代码看起来有点像这样 不是真正的代码 只是一个例子 template