gpt4 book ai didi

c++ - 用作默认参数的未优化 constexpr 的 undefined reference

转载 作者:行者123 更新时间:2023-11-30 02:14:51 25 4
gpt4 key购买 nike

我不明白为什么下面的代码使用 GCC 优化编译,但在未优化时无法链接到“对 `base::A_VAL' 的 undefined reference ”。我在做一些狡猾的事吗?这是编译器错误(从来不是)吗?这是在 Ubuntu 上使用 g++ 5.4.0。

基础.h:

class base {
public:
static constexpr unsigned int A_VAL{0x69U};
};

派生.h:

#include "base.h"
#include <iostream>

using namespace std;

class derived : public base
{
public:
int some_func(void) {
cout << "Some func" << endl;
return 0;
}
};

混凝土.h:

#include "derived.h"

#include <utility>

class concrete : public derived
{
public:
concrete(int a, std::pair<unsigned int, unsigned int> data = {A_VAL, A_VAL}) {
some_func();
std::cout << "First: " << data.first << " Second: " << data.second << endl;
}
};

测试.cpp:

#include "concrete.h"

int main (int argc, char *argv[])
{
concrete c{1};

c.some_func();
}

g++ -O2 -std=c++14 -o test test.cpp

很好。

g++ -O0 -std=c++14 -o test test.cpp

/tmp/ccm9NjMC.o: In function `main':
test.cpp:(.text+0x23): undefined reference to `base::A_VAL'
test.cpp:(.text+0x28): undefined reference to `base::A_VAL'
collect2: error: ld returned 1 exit status

最佳答案

在优化 GCC 时可能能够确定(在内联常量折叠之后)concrete 的主体的构造函数几乎可以替换为

some_func();
std::cout << "First: " << A_VAL << " Second: " << A_VAL << endl;

Since operator<< for the standard stream类按值取整数,A_VAL是常量表达式,上面的调用不需要为 A_VAL 存储任何内容.它的值只是插入。因此,GCC 不需要 A_VAL 的类外定义。 ,这是静态类成员通常需要的。

当不优化时,GCC 很可能会初始化 pair 对象。 std::pair 's constructor通过引用获取对象,而引用需要绑定(bind)到一个对象。所以 A_VAL 的定义成为必需的,因此链接器会提示。

您需要在某处定义对象(C++17 之前)

// At namespace scope
constexpr unsigned base::A_VAL;

或者切换到编译为 C++17。那么A_VAL (与所有 constexpr 静态成员数据一样)将隐含为内联变量,编译器将自行解析其定义。

关于c++ - 用作默认参数的未优化 constexpr 的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57070804/

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