簡體   English   中英

未優化的constexpr的未定義參考用作默認參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM