gpt4 book ai didi

c++ - 在clang 11上显式模板实例化期间的编译器段错误

转载 作者:行者123 更新时间:2023-12-03 10:04:39 25 4
gpt4 key购买 nike

以下显式模板实例化导致 LLVM 下的编译器前端段错误 clang++ 11.0x86_64-pc-windows-msvc , 使用 clang-cl-std=c++17 的接口(interface),无论优化级别如何。A.h

template <typename T>
class A
{
public:

T value;

static constexpr auto address = &A<T>::value;
};

extern template class A<float>;
A.cpp
#include "A.h"

template class A<float>;
请注意,由于 C++17 A::address是一个内联变量,因此在这里使用 ODR 不会成为问题。
编译器的行为显然是错误的,我已经在 LLVM 错误跟踪器上提交了一份报告。
尽管如此,我仍然对代码的实际正确性感到好奇。
它是编译器错误处理的未定义行为,还是代码本身没有任何问题并且仅与编译器有关。就个人而言,我在显式模板实例化规范的标准中没有发现任何表明上述代码错误的内容。
我不认为上述内容不正确,我是否遗漏了什么?

最佳答案

您的示例类A

// A.h
#pragma once

template <typename T>
class A {
public:
T value;
static constexpr auto address = &A<T>::value;
};

extern template class A<float>;

// A.cpp
#include "A.h"

template class A<float>;

使用例如如以下示例(完整 demo here )
#include <iostream>
#include "A.h"

int main() {
A<float> af{42.F}; // uses explicit instantiation: no implicit instantiation occurs.
A<int> ai{43}; // implicit instantiation.
std::cout << af.*A<float>::address // 42
<< "\n" << ai.*A<int>::address; // 43
}
格式正确,编译器崩溃自然是(ICE;内部编译器错误)编译器错误。除非您自己的程序还包含不小心放置的显式特化(见下文)或与上面的最小示例非常不同,否则您自己的程序同样应该是格式良好的。

细节
[temp.explicit]/14需要,对于显式实例化声明 [ 重点矿]:

If an entity is the subject of both an explicit instantiationdeclaration and an explicit instantiation definition in the sametranslation unit, the definition shall follow the declaration. Anentity that is the subject of an explicit instantiation declarationand that is also used in a way that would otherwise cause animplicit instantiation in the translation unit shall be the subjectof an explicit instantiation definition somewhere in the program;otherwise the program is ill-formed, no diagnostic required. [...] Anexplicit instantiation declaration shall not name a specialization ofa template with internal linkage.


这些要求都满足了上面的例子, A 的定义的要求也是如此。根据 [temp.explicit]/5 在其特化的明确定义之前.
最后, [temp.spec]/5包含 [ 的附加要求重点矿]:

For a given template and a given set of template-arguments,

  • (5.1) an explicit instantiation definition shall appear at most once in a program,
  • (5.2) an explicit specialization shall be defined at most once in a program, as specified in [basic.def.odr], and
  • (5.3) both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless theexplicit instantiation follows a declaration of the explicitspecialization. An implementation is not required to diagnose aviolation of this rule.

(5.1) 被满足为 A<float> 的显式实例化定义位于单个翻译单元内(一个常见的格式错误的 NDR 错误是不小心将显式实例化定义放在 header 中,其中 header 包含在多个源文件中)。 (5.2) 不适用,因为 A 没有明确的特化存在(对于任何特化),并且 (5.3) 随后不适用,因为 A<float> 没有明确的特化可能与后者的显式实例化定义冲突的特化。

最后请注意,根据 [temp.local]/2 , 你可以使用注入(inject)类名 A初始化静态数据成员时 address类模板的 A :
template <typename T>
class A {
public:
T value;
static constexpr auto address = &A::value;
};

关于c++ - 在clang 11上显式模板实例化期间的编译器段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65613231/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com