【问题标题】:Bad instanition in function that is not itself instantiated. Difference in behaviour between clang and gcc [duplicate]本身未实例化的函数中的错误实例化。 clang和gcc之间的行为差​​异[重复]
【发布时间】:2020-09-07 18:24:35
【问题描述】:

考虑以下 c++ 程序:

template<typename X>
struct S
{
    X x;
};

template<typename>
void f()
{
    S<void> s;
}

int main()
{
}

使用“-std=c++17 -pedantic-errors”编译时,clang 会出现编译错误,但 gcc 不会出现编译错误。

c++ 标准对这个程序有什么看法?它是否有效?如果它无效,它是否有未定义的行为?

如果回答这个问题的人可以继续并在他们的回答中包含 c++ 标准的相关部分,那就太好了。

编译器资源管理器链接来试试这个:https://godbolt.org/z/Ke1K7b

【问题讨论】:

  • f() 永远不会被实例化。将f&lt;int&gt;(); 添加到主目录。

标签: c++ templates language-lawyer


【解决方案1】:

您的函数模板使程序格式错误,无需诊断。

[温度分辨率]

8 模板的有效性可以在任何之前检查 实例化。 [注意:知道哪些名称是类型名称允许 以这种方式检查的每个模板的语法。 ——尾注] 程序格式错误,不需要诊断,如果:

  • 无法为模板或模板中的 constexpr if 语句的子语句生成有效的特化,并且 模板未实例化,或

无论你用什么实例化f,它都会导致一个无效的声明。所以它与那个段落匹配。

Clang 会立即检查,而 GCC 不会,但两种方法同样有效。无论哪种方式,问题在于模板中的构造,而不是编译器。

【讨论】:

  • 感谢您的回答。一个后续问题:如果我替换 S s; with if constexpr (false) { S s;在这种情况下仍然是未定义的行为?
  • @Supremum - 是的,我会这么说。 if constexpr 分支就像一个从未实例化的模板。它仍然是格式不正确的 ndr。
  • @cigien - S&lt;void&gt; 可以特化为有效并不重要。该专业化仍然需要在之前 f 可见,因为S&lt;void&gt; 类型不相关。它是不可见的,所以它只是我们插入 [temp.res]/8 的无条件无效构造。
  • 啊,对,有道理,S&lt;void&gt; 也需要依赖,而不仅仅是 if constexpr 条件。
  • @Supremum - [temp.res]/8 有很多子句,如果您有更多的场景,我建议您输入链接并阅读它们。您的最新问题已经出现在 LanguageLawyer 坚持的问题中,指向 timsong-cpp.github.io/cppwp/n4861/temp.res#8.4
猜你喜欢
  • 1970-01-01
  • 2017-10-09
  • 2013-02-01
  • 2013-01-24
  • 1970-01-01
  • 2012-08-14
  • 2022-10-25
  • 2020-12-14
  • 1970-01-01
相关资源
最近更新 更多