簡體   English   中英

未優化的 g++ 4.9 上靜態 constexpr 的未定義引用

[英]undefined reference for static constexpr on g++ 4.9 with no optimisation

我有以下代碼:

#include<chrono>
#include<iostream>

using namespace std::chrono_literals;

#define MSG "hello"
#define DUR 1000ms

class mwe{
    public: 
    static constexpr auto msg = MSG;
    static constexpr auto dur_1 = DUR;
    static constexpr std::chrono::milliseconds dur_2 = DUR;
    static const std::chrono::milliseconds dur_3;
    static constexpr decltype(DUR) dur_4 = DUR;
};

constexpr std::chrono::milliseconds mwe::dur_2; 
const std::chrono::milliseconds mwe::dur_3 = DUR; 
constexpr decltype(DUR) mwe::dur_4;

int main(void) {
    std::cout << "str: " << mwe::msg << std::endl;
    std::cout << "dur_1: " << mwe::dur_1.count() << std::endl;
    std::cout << "dur_2: " << mwe::dur_2.count() << std::endl;
    std::cout << "dur_3: " << mwe::dur_3.count() << std::endl;
    std::cout << "dur_4: " << mwe::dur_4.count() << std::endl;
}

如果我編譯它(g++ 4.9),通過

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

一切都按預期工作,但如果我通過編譯

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

我收到以下錯誤:

undefined reference to `mwe::dur_1'

我個人喜歡這種方式,dur_1 被定義和聲明得最多,但如果沒有啟用優化,它在我的版本中不適用於 g++。 因為我知道的所有其他方式(dur_2、dur_3、dur_4)都有其缺點(值的冗余,沒有自動類型推導,例如,如果我將 1000 毫秒更改為 1 秒,也一樣。)

你知道嗎,如果這是一個 gcc 錯誤,編譯在生產模式下工作,但沒有優化就無法工作?

是否有另一種可能的方法來讓這個工作,而無需在課程之外定義 dur_x 的位置?

這不是編譯器中的錯誤。

odr 使用了dur1但從未定義過它。 而且, constexpr和內聯初始化程序都不會將該聲明作為定義。

[C++11, C++14: 9.4.2/3]:如果非 volatile const static數據成員是整型或枚舉類型,則其在類定義中的聲明可以指定一個大括號或等號初始值設定項其中每個作為賦值表達式的初始化子句都是一個常量表達式(5.19)。 可以在類定義中使用constexpr說明符聲明文字類型的static數據成員; 如果是這樣,它的聲明應指定一個大括號或等號初始化器,其中每個作為賦值表達式的初始化器子句都是一個常量表達式。 [ 注意:在這兩種情況下,成員都可能出現在常量表達式中。 —尾注 ]如果在程序中使用 odr (3.2) 並且命名空間范圍定義不應包含初始化程序,則該成員仍應在命名空間范圍中定義。

與往常一樣,優化級別可能會影響編譯器能夠和/或願意報告此類錯誤的程度。

您可以編寫以下內容來定義您的成員:

#include<chrono>

using namespace std::chrono_literals;

#define DUR 1000ms

struct T
{
   static constexpr auto dur_1 = DUR;
};

constexpr decltype(T::dur_1) T::dur_1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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