使用 C++11 编译时出现未定义的引用错误
示例程序在这里:
test.h
#pragma once
#include <bitset>
class Foo{
public:
constexpr static std::bitset<9> hori1{0b111000000};
bool Bar(const std::bitset<9> cells);
};
test.cpp
#include <bitset>
#include "test.h"
bool Foo::Bar(const std::bitset<9> cells){
return hori1.any();
}
int main(){
return 0;
}
在没有 --std=c++11
的情况下编译此程序时,一切正常。
$ g++ -c test.cpp
$ g++ test.o
但是当包含该标志时,我得到这样的信息:
$ g++ -c --std=c++11 test.cpp
$ g++ test.o
/usr/bin/ld: test.o: warning: relocation against `_ZN3Foo5hori1E' in read-only section `.text'
/usr/bin/ld: test.o: in function `Foo::Bar(std::bitset<9ul>)':
test.cpp:(.text+0x17): undefined reference to `Foo::hori1'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
为什么这种情况只发生在 C++11 中?据我所知,test.h 已正确包含,因此 hori1
应该在 Foo
中可见。任何帮助表示赞赏。
The example program is here:
test.h
#pragma once
#include <bitset>
class Foo{
public:
constexpr static std::bitset<9> hori1{0b111000000};
bool Bar(const std::bitset<9> cells);
};
test.cpp
#include <bitset>
#include "test.h"
bool Foo::Bar(const std::bitset<9> cells){
return hori1.any();
}
int main(){
return 0;
}
When compiling this program without the --std=c++11
everything works fine.
$ g++ -c test.cpp
$ g++ test.o
But when the flag is included, I get this:
$ g++ -c --std=c++11 test.cpp
$ g++ test.o
/usr/bin/ld: test.o: warning: relocation against `_ZN3Foo5hori1E' in read-only section `.text'
/usr/bin/ld: test.o: in function `Foo::Bar(std::bitset<9ul>)':
test.cpp:(.text+0x17): undefined reference to `Foo::hori1'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
Why is this happening only in C++11? As far as I know, test.h is correctly included and therefore hori1
should be visible from within Foo
. Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
hori1
是静态
。您必须在类的实现中定义静态数据成员。测试.cpp
:hori1
isstatic
. You have to definestatic
data members in the implementation of the class.test.cpp
:问题是,在 C++11 中,我们必须在类外部的一个翻译单元中为 static constexpr 声明添加相应的定义 > 类的数据成员(如果使用了 odr)。下面更详细地解释了这一点:
C++11
在上面的代码片段(适用于 C++11、C++14)中,我们有一个 <类内部静态数据成员
OUT_OF_BOUNDS_VALUE
的strong>声明。因此,在恰好一个翻译单元中,我们必须提供相应的定义。否则,您将收到链接器错误,可以在此处查看。也就是说,在 恰好一个 翻译单元中,我们应该编写:
在使用 没有初始化程序程序将运行。 演示
C++17
在上面的代码片段中(适用于C++17< /em>)我们在类内部有静态数据成员
OUT_OF_BOUNDS_VALUE
的定义。因此,从 C++17 开始,我们不必在其他任何地方提供 OUT_OF_BOUNDS_VALUE 的定义,因为我们已经在类中定义了它,因此是同一个程序工作,没有任何链接器错误。The problem is that in C++11, we have to add a corresponding definition outside the class in exactly one translation unit for a static constexpr declaration of a class' data member(if odr-used). This is explained in more detail below:
C++11
In the above code snippet(which is for C++11,C++14), we have a declaration of the static data member
OUT_OF_BOUNDS_VALUE
inside the class. And so, in exactly one translation unit we have to provide a corresponding definition. Otherwise you'll get a linker error which can be seen here.That is, in exactly one translation unit we should write:
After adding the above out of class definition with no initializer the program will work. Demo
C++17
In the above code snippet(which is for C++17) we have a definition of the static data member
OUT_OF_BOUNDS_VALUE
inside the class. So since C++17, we don't have to provide the definition ofOUT_OF_BOUNDS_VALUE
anywhere else since we already have a definition for it inside the class and thus the same program works without any linker error.