Re: [問題] const 變數在.h, undefined behavior?

看板C_and_CPP作者 (IS YOU)時間4年前 (2019/07/25 18:21), 4年前編輯推噓6(607)
留言13則, 3人參與, 4年前最新討論串2/2 (看更多)
我回文整理一下好了, 推文好像會越推越長 ※ 引述《lovejomi (JOMI)》之銘言: : https://www.fluentcpp.com/2019/07/23/how-to-define-a-global-constant-in-cpp/ : 偶然看到這篇,我其實覺得他寫錯 : 這部分 : Each file has its own version of焏. This is a problem for three reasons: : it is undefined behaviour (objects must be defined only once in C++), : ??????真的undefined嗎?有沒有什麼表格或網址整理ub...之前看到說把東西寫在 : namespace std也是ub...也太多很容易就寫出來的ub了吧 一個很令人沮喪的事實是 C++ 確實很多很容易寫出來的 UB... : it uses more memory, : if the constructor (or destructor) of曱温as side effects, they will be execute : d twice. : 這句看不懂,什麼是side effect在這裡? : 他的範例我唯一能看出問題的就是你沒辦法保證cout比他的x先初始化 : 其他他說執行兩次cstor不是很正常嗎?

07/25 17:44,
執行兩次 ctor 正是他的第三點在說的
07/25 17:44

07/25 17:45,
你以為只有一個全域變數其實有兩個
07/25 17:45

07/25 17:45,
其證據即是建構子被執行了兩次
07/25 17:45

07/25 17:48,
那在同一支程式裡有兩個同名字的不同全域變數即是 UB 了
07/25 17:48

07/25 17:49,
這是明確違反 one-definition rule 的 UB
07/25 17:49
One Definition Rule (ODR) 是 C++ 裡的一個很重要的概念 重要到標準裡有一個衍生詞叫做 "odr-used" 來形容一個東西 被如此形容的東西在整支程式的所有轉譯單元當中有且僅能有恰好一個定義 : 我只記得const自帶static,所以預設是internal linkage : https://en.cppreference.com/w/cpp/language/cv : 的Note也是這樣寫 : 但他說是ub 我覺得很奇怪….. 不過下面的回應好像有跟你一樣的問題: qsvui ‧ 2 days ago I'm not sure that your very first example of putting a const variable in the header is undefined behavior. 他舉了跟你提到的同樣的段落表示怪怪的 : 最後他提到inline, : inline跟extern效果一樣,意思是c++鼓勵使用inline而不是extern嗎 : 謝謝

07/25 17:50,
後半篇文章的 inline (C++17) 和 extern (pre-C++17)
07/25 17:50

07/25 17:51,
它們的作用並不一樣: "It looks somewhat similar to
07/25 17:51

07/25 17:51,
inline, but its effect is very different."
07/25 17:51
文中很明確的跟你說了: With extern, the above code is a declaration, and not a definition. With inline, it was a definition. extern 只做宣告不做定義, 所以可以在各個不同轉譯單元當中同時存在 但是若它被 odr-used 那你就必須給它一個定義 因此你必須在其中一個轉譯單元中定義它 C++17 的 inline 變數跟以前的 inline 函數的概念頗像 (或者該說就是這樣延伸來的) 它能夠有多於一個定義, 只要大家的定義完全相同即可 所以在 C++17 我們可以像貼 inline 函數一樣為全域變數貼 inline 編譯器就知道這些在各個轉譯單元中宣告 inline 的變數是同一個東西而把它整合在一起 而由於這已經是個定義, 因此就無須特別在其中一個轉譯單元中定義之了 (反而這裡再多定義就違反 inline 的完全相同的約定, 那這就又是 UB 了) -- 有人喜歡邊玩遊戲上逼; 也有人喜歡邊聽歌打字。 但是,我有個請求, 選字的時候請專心好嗎? -- 改編自「古 火田 任三郎」之開場白 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 180.177.3.123 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1564050073.A.CDC.html

07/25 18:49, 4年前 , 1F
07/25 18:49, 1F

07/26 11:43, 4年前 , 2F
所以好像是不是ub也不明確,但我們常常在cpp 寫一些cons
07/26 11:43, 2F

07/26 12:02, 4年前 , 3F
在global, 只要兩個cpp都不小心這樣寫撞名 難道就ub?這
07/26 12:02, 3F

07/26 12:02, 4年前 , 4F
樣要怎麼寫code...
07/26 12:02, 4F

07/26 17:39, 4年前 , 5F
1.你可以寫個singleton統一管理全域物件
07/26 17:39, 5F

07/26 17:40, 4年前 , 6F
2.不喜歡singleton,還可以拿個namespace包起來防撞名
07/26 17:40, 6F

07/26 17:43, 4年前 , 7F
3.你其實沒那麼需要讓大家都爽爽看的全域變數,不是貪
07/26 17:43, 7F

07/26 17:45, 4年前 , 8F
圖方便,就是對scope跟權責的控制沒有觀念
07/26 17:45, 8F

07/26 17:52, 4年前 , 9F
如果是後者,比起研究那些是UB然後不要踩雷,花時間去
07/26 17:52, 9F

07/26 17:53, 4年前 , 10F
學這些設計原則才是真的
07/26 17:53, 10F

07/27 09:49, 4年前 , 11F
可是你明明知道 const int 是internal linkage 你不該會
07/27 09:49, 11F

07/27 09:49, 4年前 , 12F
想擺在無名namespace吧? 多多少少寫cpp會想named magic
07/27 09:49, 12F

07/27 09:49, 4年前 , 13F
number in global啊 撇除constexpr
07/27 09:49, 13F
其實說到 linkage 我在想會不會這種習慣/誤解有可能是因為在 C 語言這個是 external linkage 有關 同樣引用你舉過的那個地方: > ... This is different from C where const file scope variables have external > linkage. 在 C 的時代已經這樣理解/這樣被教導所以到了 C++ 照樣帶了進來這樣 不說別的, 我自己在仔細找過資料之前也有差不多的誤解... ※ 編輯: LPH66 (180.177.3.123 臺灣), 07/27/2019 12:49:42
文章代碼(AID): #1TEOAPpS (C_and_CPP)
文章代碼(AID): #1TEOAPpS (C_and_CPP)