是否存在常量的c ++临时rvalue

时间:2016-06-11 17:49:55

标签: c++ c++11

当将文字常量/基本类型赋给变量时,是否在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/

另外,我认为我完全错了

2 个答案:

答案 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;

然后只是打印1030的明显优化就出现了。

当以这种方式推理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更关注关于“通过价值传递”和最小化类临时对象的不必要副本的首要争论。除非您过早地进行优化,否则没有理由关心文字类型,无论是否创建临时文字。