Re: [問題] constexpr觀念釐清

作者: Feis (永遠睡不著 @@)   2019-02-06 20:33:46
※ 引述《lovejomi (JOMI)》之銘言:
<deleted>
: 1. 他提到 constexpr function預設是inline, 意思是說假設用在runtime的情境下
: 會"建議" compiler用inline的方式對吧?
: 這邊衍伸一個問題是
: https://stackoverflow.com/a/4193698
: 為什麼inline function寫在header 不會有redefine的error, 而一般函數卻會?
: 兩個應該都是external linkage, 為什麼一個會用ODR去解釋一個就是redefine?
: ODR我經驗上是 有兩個class同名 member function又剛好都呼叫同一個名字的
: compiler只會link一個 然後就會莫名的只走一個版本的class實作
: 但為什麼inline跟non-static function會用兩個方式去解釋呢?
inline 函式的設計就是 "允許" 編譯器在可以的情況下直接 inline
帶來的效果就是每個編譯單元 (translation unit) 都可以有自己的一份
但是確保不同份之間行為需要一致的工作就是交給程式設計師自己負責
其他的情況也類似,就是個想提供編譯器優化彈性的動機下,讓使用者自己負責
: 2. 我是否能夠把每一個function (看起來可能是可以compile time算出來的function)
: 無腦加上constexpr (反正若用在需要compile time知道常數值的時候compiler會報錯
: 再修就好)? 若可以這樣無腦加上去 是不是有可能讓程式變快?
: 這邊也有個問題是, 網站例子
: constexpr int i = gcd(11,121);
: 是否gcd函數沒加上constepxr的話, compiler就"不允許" 在compile time做計算優化
: 或是說 int i = gcd(11,121); 兩個都不加上constexpr,
: 是不是完全都不會再compile time做優化?
: 如果答案是 都會優化的話 是否代表 constexpr 只是給reader明確讀code的時候
: 可以清楚知道這件事?
: (當然要把這函數用在template那種compile time要知道數值的情況是一定要加的)
被標記為 constexpr 的 function 才能在語意上成為 constant expression
以常見的陣列長度為例:
int a[f()];
f 如果沒被標記為 constexpr 則這邊的 f() 就不會是語意上的 constant expression
因此在標準如果不支援 VLA (Variable-length array) 的情況下,這樣的寫法是不合法的。
所以這邊要避免發生 VLA 就要: f 已被定義且為 constexpr
實務上使用的問題是,就我所知,就算有不該被標記為 constexpr 的 function,
編譯器也沒被要求在誤標記的情況下都要丟錯,可能就會默默吞下忽略 constexpr
除非忽略的情況下會造成其他的語法錯誤,不然不易發覺
所以目前 constexpr 確實對於 library 的設計影響比較大,
可以用來讓 client 明確知道可否用於 constant expression
舉個例子, 在 C++ 裡面使用 numeric_limits<int>::max() 取代 INT_MAX 來避免使用 macro
但是 INT_MAX 一直可作為 case 常數值使用:
switch (INT_MAX) {
case INT_MAX:
break;
}
但 numeric_limits<int>::max() 在舊有標準卻不行:
switch (numeric_limits<int>::max()) {
case numeric_limits<int>::max():
break;
}
在新版標準支援 constepxr 才能讓上面這個例子能用, 當然這問題在作為模板引數時會更明顯
而優化就是看編譯器心情,只是知道越多編譯器越有機會優化。
相對地,加上 constexpr 必須要小心編譯期與執行期的差異,有機會產生不同的結果
例如常見的浮點數計算,可能發生在編譯期計算與執行期計算結果不一的問題
: 3. 既然constexpr有牽扯到compiler optimization, 是否變成就算用A compiler可以
: 編譯過, 拿到B compiler很可能無法編譯? 造成不可攜
優化與語法語意無關,在符合相同標準的情況下不應該有無法編譯的問題
但是可攜性牽涉的範圍很廣,可以編譯不代表結果相同

Links booklink

Contact Us: admin [ a t ] ucptt.com