[英]Why do global inline variables and static inline members in C++17 need guards?
[英]Can initialization order of global variables across TUs be forced with C++17 inline members?
這主要是一個好奇心驅動的問題,我不打算寫這樣的代碼。 這是我關於動態初始化順序的回答的后續。
根據我在答案中的介紹,內聯靜態成員變量按照它們的類在源代碼中出現的順序進行初始化,如果這種順序在它們都出現的所有翻譯單元 (TU) 中是相同的。
此外, [basic.start.dynamic]-3.1節適用於部分有序(其他內聯靜態)和有序變量。 這意味着同一 TU 中的普通全局變量。
所以,給定這個例子:
//A.hpp
struct A{
inline static int a=foo();// Some function with possible side-effects
};
//B.hpp
struct B{
inline static int b=foo();
};
//X.cpp
int x1 = foo();
#include "A.hpp"
int x2 = foo();
#include "B.hpp"
int x3 = foo();
//Y.cpp
int y1 = foo();
#include "A.hpp"
int y2 = foo();
#include "B.hpp"
int y3 = foo();
變量是否按以下順序初始化?
(x1,y1)
以不確定的順序,a
,(x2,y2)
以不確定的順序,b
,(x3,y3)
以不確定的順序。此外,如果翻譯單元只有一個類,規則是否仍然適用?
//Z.cpp
int z1 = foo(); // Initialized with (x1,y1) ?
#include "A.hpp"
int z2 = foo(); // Initialized with (x2,y2) or anytime later ?
特別是,包含A::
創建一個屏障來保證z2
在(x1,y1)
之后初始化?
結果:
g++ 10.1.0: x1=1 a=2 x2=3 b=4 x3=5 y1=6 y2=7 y3=8 z1=9 z2=10
clang++ 10.0.0: a=1 b=2 x1=3 x2=4 x3=5 y1=6 y2=7 y3=8 z1=9 z2=10
兩個編譯器都至少對一組x,y
變量打破了我的假設。 我錯過了什么? 主要是我參考這個
如果 V 和 W 具有有序初始化並且 V 的定義在 W 的定義之前是外觀有序的,或者如果 V 具有部分有序初始化,則 W 沒有無序初始化,並且對於 W 的每個定義 E 都存在一個定義 D的 V 使得 D 在 E 之前出現順序,然后
我讀錯了這一段嗎? 我不太確定 ors 和 ands。
讓我們稍微簡化一下您的示例,使其更易於理解:
// X.cpp
int x1 = foo();
inline int a = foo();
int x2 = foo();
// Y.cpp
int y1 = foo();
inline int a = foo();
int y2 = foo();
您的問題是x1
是否保證在y2
之前初始化, y1
是否保證在x2
之前初始化。
答案是不。 正如我在另一個答案中所解釋的,動態初始化的偏序規則的影響是,extern 內聯變量的每個翻譯單元的“實例”在理論上被視為一個單獨的變量; 對象本身(其中只有一個)在第一次初始化任何相應的概念變量時被初始化。
例如,一個特定的排序會在 Y 翻譯單元之前執行整個 X 翻譯單元。 在這種情況下,初始化的順序是x1
、 a
、 x2
、 y1
、(沒有操作,因為a
之前已初始化)、 y2
。 (編譯器同樣可以在 X 中的所有內容之前對 Y 中的所有內容進行排序,或者將它們交錯。)
引用的 [basic.start.dynamic]/3.1 來自比我在回答中考慮的更新版本的標准,但基本邏輯是相同的。 讓V
= x1
和W
= y2
。 根據 3.1,如果V
將在W
之前初始化
V
和W
已經有序初始化並且V
的定義在W
的定義之前是外觀有序的,
“或者”
V
有部分有序的初始化,W
沒有無序的初始化,對於W
每個定義E
都存在一個V
的定義D
,使得D
在E
之前是出現順序的
第一個條件不滿足,因為V
在W
之前沒有出現順序。 第二個條件也不滿足,因為V
和W
都只有一個定義,而且正如我所說,它們不是按外觀排序的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.