gpt4 book ai didi

c++ - 我应该避免静态 constexpr 局部变量吗?如果是这样,为什么?

转载 作者:行者123 更新时间:2023-12-04 17:13:08 24 4
gpt4 key购买 nike

考虑如下代码,其中 literal some_magic_int(例如 3)被赋予一个名称,只是为了更清楚地说明它代表的常量:

void f() {
static constexpr int this_variable{some_magic_int};
do_something_with(this_variable);
}
int main() {
// ...
f();
// ...
}

我很确定 constexpr 必须在这里:some_magic_int 是文字,所以它永远不会改变,我给它起个名字只是为了清楚,而不是给出一个改变它的方法,所以它至少应该是 const;那为什么不在编译时使用 constexpr 呢?

但是 static 呢?只是没有必要吗?还是有害的?如果是这样,为什么?而且,当在局部变量声明中与 constexpr 配对时,它是否有任何可观察到的效果?


关于 question to which this is marked as duplicate of ,它是关于 static constexpr int x [] = {},而不是 static constexpr int x {}。这至少突出了那种情况(应用于 x 指针的属性与应用于 *x 指针的属性)和我的情况(没有指针)之间的至少一个区别。


此外,一旦我将 constexpr 添加到局部变量的说明符(在有意义的地方,例如添加到 int),我就说该变量是编译的-时间已知。为什么这并不意味着不需要任何运行时实体?

最佳答案

该标准实际上从未谈论过编译时,只是说在执行前检查类型和实例化模板。这意味着这个程序必须被诊断(而不是“拒绝”!),即使非常量数组长度和模板参数从未被“使用”并且可能被解释器合理地忽略:

template<int> void f() {}
int main(int argc,char **argv) {
if(false) {
int buf[argc]; // accepted by a common extension
f<argc>();
}
}

除此之外,语义是每个评估都是程序普通执行的一部分,而常量折叠就像任何其他优化一样只是一种优化。 (毕竟,我们可以优化 argc*2*3*4,即使它不包含 可能 是常量表达式的非文字子表达式。)对于常量表达式,这很大程度上是不可观察的,因为常量评估不会有副作用(这也避免了常量初始化的非 block 变量之间的交互)。但是,它可以通过局部变量的地址产生差异:

bool introspect(const int *p=nullptr) {
constexpr int x=0;
return p ? p==&x : introspect(&x); // always false
}

如果这些变量的地址转义,编译器必须让这些变量占用内存,这是对先前标记为重复的答案的大部分内容。因此,首选 static 是有意义的,除非对象很大且其地址无关紧要(例如,用作模板参数或通过递归)。

关于c++ - 我应该避免静态 constexpr 局部变量吗?如果是这样,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69129171/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com