【问题标题】:Get similar behavior between Clang and GCC for uninstantiated templates?对于未实例化的模板,在 Clang 和 GCC 之间获得类似的行为?
【发布时间】:2015-06-06 02:26:09
【问题描述】:

对于从未实例化的模板代码,GCC 似乎比 Clang 更宽容。我有一个使用g++-5.1(使用-Wall -Wextra -Wdeprecated -Wno-comment -Wnoexcept)在没有警告或错误的情况下编译的代码库,但使用clang++-3.7 会发出许多关于模板代码的错误,除非我指定-fdelayed-template-parsing。这个标志的文档非常稀缺。我只能找到描述其行为的single sentence

-fdelayed-template-parsing 让 clang 延迟解析函数模板定义,直到翻译单元结束。

即使这看起来可能是不正确的——我认为问题在于模板正在被解析,并且该标志实际上允许 Clang无需永远解析相关模板即可完成编译。

所以我想知道:

  1. -fdelayed-template-parsing 的行为与 GCC 的默认行为有多相似?该选项本身基于 MSVC,正如标志名称所暗示的那样,它甚至不检查基本语法问题,例如未实例化的模板代码中缺少分号。我相信 GCC 在这里比 MSVC 走得更远,那么这个标志实际上是否使 Clang 比 GCC 限制更少
  2. 反过来说,有没有办法让 GCC 在这方面表现得更像 Clang,通过针对未实例化模板中的非法代码发出错误或至少是警告?

编辑:根据要求,这是一个模板的简单示例(如果未实例化)不会导致 GCC 出错但 导致 Clang 出错:

template <typename T>
std::string neverInstantiated(void)
{
    return 3;
}

显然,由于模板参数未使用,因此无论如何实例化,这都是严重错误的。

【问题讨论】:

  • 您能否提供一个示例,说明在 clang 上出错但在 gcc 上没有错误?
  • 如果模板没有有效的特化,则程序是非良构 NDR。两个编译器同样正确。
  • @Brian 那又怎样?我的问题不是“哪个(更)合规”,而是“我能得到类似的行为吗”。由于 GCC 和 MSVC 都允许这样做,而 Clang 可以 允许这样做,因此有大量的生产代码库使用它,因此即使基于标准的答案是“程序是格式不正确。”这就是为什么我没有询问标准的内容。
  • @KyleStrand 好吧,(目前)编译格式错误的程序真的没有意义,是吗?
  • @KyleStrand (1) 对于 anwser 来说是微不足道的,当您添加 -fdelayed-template-parsing 时,clang 的限制确实比 gcc 少,只需删除函数模板中的分号即可证明这一点。对于(2),为什么要这样做?如果您同时使用 gcc 和 clang 进行编译,请使用后者的诊断程序来修复格式错误的程序。

标签: c++ templates c++11 g++ clang++


【解决方案1】:

来自 [temp.res]:

如果无法为模板生成有效的特化,并且该模板未实例化,则模板格式错误,无法诊断 必填。

所以两个编译器在这方面都有有效的行为。

但是,与其试图让 clang 不发出诊断,或者试图让 GCC 发出一个...我认为最好在这里利用 clang 的附加诊断并简单地删除格式不正确的模板!为什么你还要用无效代码污染你的代码库?

【讨论】:

  • 有几个原因不能简单地批量删除模板。一个很简单,它们足够多(......我没有写它们......)找到和删除未使用的将花费大量时间,而且没有太多收获(因为两个编译器 都可以 使用不正确的模板进行编译)。另一个是它不是我的代码,我认为我无法删除它(我不是很有经验,等等)。最后,它们被认为是“潜在有价值的”,因为这些模板在未来可能有用(即,如果我们在某个时候实际实例化它们)。
  • @KyleStrand 好吧,你不能实例化它们(那将是一个硬错误),所以它们不可能很有潜在价值......永远。
  • 当然,当我们添加实例化它们的代码时,我们也会修复模板代码(对于我们实际实例化的每个模板)。如果我们碰巧有时间,我们可能会在我们真正需要它之前尝试修复无效代码(YAGNI,但是......好吧,它可能不是我的电话),因此对诊断的渴望不是硬错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多