当将文字常量/基本类型赋给变量时,是否在C ++中生成临时值?这在C ++规范(c ++ 98,c ++ 11,c ++ 14,c ++ 17等)之间有区别吗?
int a = 1; // 1 here is likely loaded in microcode level, right? But not guaranteed not to generate a temp value
int b = 1+2; // evaluated to 3 at compile time as const, also 3 might not exist in microcode. Likely temp value
auto c = 3; // creates an int based on 3. No temp value
int a{1}; //no temp value?
我正在阅读https://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/。
另外,我认为我完全错了
答案 0 :(得分:3)
C ++语言由标准定义。在标准中,它描述了一个抽象机器的行为,该机器在完成由标准定义的行为的良好程序上运行。
C ++的核心规则是 as-if 规则。在 as-if 规则下,编译器生成的代码可以自由地运行但它需要,只要它在标准下可观察到的行为符合标准的状态。
根据标准,无法在1
中观察1+2
的存在。因此,根据标准,编译器可以自由编译1
从未存在的代码,只需生成数字3
。
此外,如果您从未使用变量x
,则声明
int x = 1+2+3+4;
无效。因此编译器可以自由使用它。实际上,您永远不会引用值x
或更改其值,然后可以从程序中完全消除变量x
。无论何时使用,值10
都可以替换它。
通常,优化编译器执行称为“静态简单分配”的操作,即使您多次分配给x
,它实际上也会将其视为不同变量的赋值序列< / em>的。只有当您使用x
的引用或指针时才会出现故障。
所以
int x = 1+2+3+4;
std::cout << x;
x += 20;
std::cout << x;
可以视为
const int x_0 = 10;
std::cout << x_0;
const int x_1 = x_0 + 20;
std::cout << x_1;
然后只是打印10
和30
的明显优化就出现了。
当以这种方式推理C ++时,你必须注意可观察的行为是什么,并且知道编译器可以自由地抛弃其余部分。通过一些小心操作,您可以进行零成本抽象,其中中间结果在运行时从未实际存在。
答案 1 :(得分:2)
如果我们要具体,我们必须区分临时对象和临时值。临时对象属于类类型。这就是C ++标准所讨论的以及人们在谈论“临时”时通常的意思。当人们谈论临时价值时,他们真正的意思是中间结果。即,将值交换寄存器。
您的所有示例:
int a = 1;
int b = 1+2;
auto c = 3;
int d{1};
不要创建任何“临时”,因为不必创建任何“临时”。 “1 + 2”很可能被折叠成一个常数。甚至不必生成操作码。该程序的最小程序集是:
a:
.long 1
b:
.long 3
c:
.long 3
d:
.long 1
您链接的GOTW更关注关于“通过价值传递”和最小化类临时对象的不必要副本的首要争论。除非您过早地进行优化,否则没有理由关心文字类型,无论是否创建临时文字。