[英]Undefined reference for unoptimised constexpr used as default parameter
我不明白為什么下面的代碼用GCC優化編譯,但未經優化時無法鏈接到“base :: A_VAL'的未定義引用”。 我做狡猾的事嗎? 這是一個編譯器錯誤(永遠不會)嗎? 這是在Ubuntu上使用g ++ 5.4.0。
base.h:
class base {
public:
static constexpr unsigned int A_VAL{0x69U};
};
derived.h:
#include "base.h"
#include <iostream>
using namespace std;
class derived : public base
{
public:
int some_func(void) {
cout << "Some func" << endl;
return 0;
}
};
concrete.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;
}
};
TEST.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;
由於標准流類的operator<<
按值獲取整數,而A_VAL
是常量表達式,因此上述調用不需要為A_VAL
任何存儲。 它的值只是插入。因此,GCC不需要A_VAL
的類外定義,正如靜態類成員通常所需的那樣。
當沒有優化時,GCC很可能初始化對對象。 std::pair
的構造函數通過引用獲取對象,並且引用需要綁定對象。 因此, A_VAL
的定義變得必需,因此鏈接器會抱怨。
你需要在某處定義對象(在C ++ 17之前)
// At namespace scope
constexpr unsigned base::A_VAL;
或者切換到編譯為C ++ 17。 然后A_VAL
(與所有constexpr
靜態成員數據一樣)將隱式地為內聯變量,編譯器將自行解析其定義。
我不確定constexpr
如何影響這個,但你只是聲明了靜態類變量,但沒有定義它。 即通常你需要constexpr unsigned int base::A_VAL{0x69U};
在.cpp文件中的某個地方。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.