作者poyenc (髮箍)
看板C_and_CPP
標題Re: [問題] constexpr 與 static const 的選擇
時間Thu Jun 13 13:33:43 2019
※ 引述《CarbonK (HTYISABUG)》之銘言:
: 開發平台(Platform): (Ex: Win10, Linux, ...)
: Linux
: 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
: GCC
: 問題(Question):
: 對於 constexpr 跟 static const 的差別不太了解
: static const 在編譯時期時
: 常數會直接儲存在執行檔的 .data 這個 segment 裡
: 這是我的理解
: 問題是 constexpr 會檢查 expression 是否為編譯期常數
: 但檢查完後它資料是仍然放在 stack 中
: 還是也會放在 .data 中
: 然後我到底該不該用 constexpr 取代 static const ?
: 還是說其實根本可以 static constexpr ?
: 麻煩大家撥冗滿足我的好奇心,謝謝
: -----
: Sent from JPTT on my Samsung SM-A810YZ.
它們擔任不一樣的角色. 先不說後端編譯器優化的部分, 先來談談
他們各自的分工:
1.
constexpr
要求編譯器在編譯時期評估 (evaluate) 數值, 或是允許
在評估數值的時候被叫用. 當你現在是
constexpr variable
的情況下,
強制其初始值必須為編譯時期可評估的.
2.
static const
在提
static const 之前, 先來講講
const.
const 可分
為
使用端和
提供端兩個角度來探討, 前者是指在使用上允
許編譯器以值不會改變的前提下做優化; 後者則是提供物
件行為不變的語意. 所以單就
const 來看,
和初始值是不
是編譯時期常數完全無關. 加上
static 儲存修飾符時,
因為
物件初始時機可能需要提早導致沒有太多選項可以用
來當初始值, 才會讓你有它跟
constexpr 可以比較的錯覺
簡單舉幾個
static const 不為編譯時期常數的例子:
1.
static local
const object
https://wandbox.org/permlink/CHGnyam7cH9PVgM1
2.
static global
const object
https://wandbox.org/permlink/vTyRAklJn4AYXBLs
從 1 可以看到: 一旦初始化時機可以不用在 main() 開始前, 就沒
必要用編譯時期常數來初始化
static const 物件. 從 2 可以看出
: 只要保證不會有 data dependency, 依舊可以在執行時期才求值
初始化.
最後來回答原po的問題, 因為這兩者的語意完全不同, 所以選擇上
就依照最能表達意圖的方式去撰寫就可以了.
--
P1389R0: Guidelines for Teaching C++ to Beginners
https://bit.ly/2GvDWKb
SG20 Education and Recommended Videos for Teaching C++
https://www.cjdb.com.au/sg20-and-videos
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.216.75.43 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1560404030.A.4C2.html
※ 編輯: poyenc (61.216.75.43 臺灣), 06/13/2019 13:37:30
推 CarbonK: 十分感謝你的回文! 06/13 22:06
→ CarbonK: 也就是說,實際上如果要保證編譯期常數就應該要用 conste 06/13 22:07
→ CarbonK: xpr 06/13 22:07
→ CarbonK: 而 static const 常常會變成編譯期常數是編譯器優化的結 06/13 22:08
→ CarbonK: 果 06/13 22:08
→ CarbonK: 我這樣的理解是正確的嗎? 06/13 22:08
→ poyenc: 你指的如果是不存在於 object file 的話, 對喔 06/14 00:20