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