C ++对带文字初始化

时间:2016-11-04 22:34:27

标签: c++

我正在深入研究C ++,并且正在努力使用用文字初始化的const引用。 e.g。

const int &r {100};

它肯定有效,但我想知道编译器使用这种定义做了什么。是否在存储器中创建了一个保持值为100的真实对象?或者在编译期间,每个r的出现在代码中只被100替换?这是我的猜测,因为初始化程序值在运行时无论如何都无法更改或引用,所以为什么要将它保存在内存中?

3 个答案:

答案 0 :(得分:2)

下面:

int

正在创建临时r,之后绑定到void foo (const std::string& s) {} foo("test"); // here temporary std::string is created and later on bound to `s` 。对const的引用将延长与其绑定的临时生命周期。

这在以下情况下更有用:

<a>

答案 1 :(得分:1)

理论上(&#34;抽象机器&#34;),文字被创建为临时文件,然后引用被绑定到它,这延长了它的生命。

在实践中,允许编译器改变它,但只要它产生相同的&#34;可观察的行为&#34;。因此编译器没有将变量保存在内存中。

您可以通过比较g++ -O0 -gg++ -O3 -g的输出以及反汇编代码来看到这一点。

短程序:

int main() {
    const int &r {100};
    return r;
}
我的计算机上的

编译时没有优化:

0x00000000004005a8 <+0>: push   %rbp 
0x00000000004005a9 <+1>: mov    %rsp,%rbp 
0x00000000004005ac <+4>: mov    $0x64,%eax 
0x00000000004005b1 <+9>: mov    %eax,-0xc(%rbp) 
0x00000000004005b4 <+12>:    lea    -0xc(%rbp),%rax 
0x00000000004005b8 <+16>:    mov    %rax,-0x8(%rbp) 
0x00000000004005bc <+20>:    mov    -0x8(%rbp),%rax 
0x00000000004005c0 <+24>:    mov    (%rax),%eax 
0x00000000004005c2 <+26>:    pop    %rbp 
0x00000000004005c3 <+27>:    retq    

与完全优化相比,内存中显然没有引用(即r只是用文字100代替):

0x00000000004005b0 <+0>:    mov    $0x64,%eax
0x00000000004005b5 <+5>:    retq   

答案 2 :(得分:0)

正式地,这会生成一个对象,然后绑定到引用,并且只要引用就生效。

有些情况下必须提供对象。考虑一下您已声明两个函数的情况,这两个函数在单独的翻译单元中定义,如下所示:

void foo(int const*);
bool bar(int const*);

现在你执行以下操作:

int main()
{
  const int& r{100};
  foo(&r);
  return bar(&r);
}

编译器不仅要将指针传递给具有正确值的对象,还必须将指针传递给同一个对象,因为它不知道其他翻译单元中的实现(可能还没有编写),例如:

namespace
{
  int const* ptr;
}

void foo(int const* p)
{
  ptr = p;
}

bool bar(int const* p)
{
  return p == ptr && *p = 100;
}

如果在这种情况下,编译器除了创建一个值为100且绑定到int的实际r对象外,还会执行其他操作,结果将不正确。