繁体   English   中英

类定义静态constexpr结构的未定义引用,g ++ vs clang

[英]undefined reference to class static constexpr struct, g++ vs clang

这是我的代码,a.cp​​p

struct int2
{
    int x, y;
};
struct Foo{
    static constexpr int bar1 = 1;
    static constexpr int2 bar2 = {1, 2};
};
int foo1(){
    return Foo::bar1; // this is ok for both clang++ and g++
}
int2 foo2(){
    return Foo::bar2; // undefined reference to `Foo::bar2' in clang++
}
int main(){ std::cout << foo2().x << std::endl; return 0; }

使用clang编译, clang++ -std=c++11 a.cpp

/tmp/a-0dba90.o: In function `foo2()':
a.cpp:(.text+0x18): undefined reference to `Foo::bar2'
clang-7: error: linker command failed with exit code 1 (use -v to see 
invocation)

g++ -std=c++11 a.cpp发出错误。

我的问题是,

  1. 谁对上述代码是正确的? clang还是g ++?
  2. 为什么bar2错误而bar1在clang中是正确的?

编译器版本:g ++ 5.4.0和clang 7.0.0

更新:问题被标记为另一个问题的副本,但事实并非如此。 我知道我可以在类之外添加显式定义来为clang传递它。 这个问题是为什么g ++和clang之间的区别。

您似乎假设如果一个编译器是正确的,另一个编译器必定是错误的。 该程序包含一个错误(然后接受它的编译器是错误的)或它没有(然后拒绝它的编译器是错误的)。 这反过来依赖于隐含的假设,即所讨论的错误,即缺少ODR使用实体的定义,是可诊断的错误。 不幸的是它不是。 该标准明确指出:

[ basic.def.odr / 10 ]每个程序应该只包含每个非内联函数或变量的一个定义,该函数或变量在废弃语句之外的程序中使用。 无需诊断

这个标准的规定是有问题的和不需要的,它就在那里。 由于缺少定义,您的程序具有未定义的行为,并且不需要实现来诊断它。 因此,两种编译器在任何优化级别上都是技术上正确的。

在具有强制复制省略的C ++ 17中,程序不再包含任何有问题的变量的ODR使用constexpr静态数据成员是隐式内联的,不需要单独的定义(感谢Oliv)。

回答我自己的问题。

我对使用odr有一些模糊的理解。

  • 对于文字类型Foo :: bar1,它没有使用odr,所以很好。
  • 对于struct Foo :: bar2:当在函数体内返回一个struct时,它将调用其复制构造函数,该构造函数引用Foo::bar2 所以Foo::bar2是odr-used,它的定义必须存在于程序的某个地方,否则会导致链接错误。

但为什么g ++不抱怨? 我想这与编译器优化有关。

验证我的猜测:

  1. 复制省略

    add -fno-elide-constructors, g++ -fno-elide-constructors -std=c++11 a.cpp

    /tmp/ccg1z4V9.o:在函数foo2()': a.cpp:(.text+0x27): undefined reference to Foo :: bar2'

    所以,是的,复制省略会影响这一点。 g++ -O1仍然通过。

  2. 函数内联

    add -fno-line, g++ -O1 -fno-elide-constructors -fno-inline -std=c++11 a.cpp

    /tmp/ccH8dguG.o:在函数foo2()': a.cpp:(.text+0x4f): undefined reference to Foo :: bar2'

结论是复制省略和函数内联都会影响其行为。 g ++和clang之间的区别是因为默认情况下g ++启用了复制省略,但clang没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM