【问题标题】:address after const_cast of a *const* variable in C++C++ 中 *const* 变量的 const_cast 之后的地址
【发布时间】:2015-03-28 00:35:46
【问题描述】:

我知道以下应该是未定义的行为 因为原始变量是 const。然而,怎么可能, &x&rx 这两个地址相同,但值 他们打印的(我不是说持有,因为它根本不可能), 不是。谢谢!

const int x=10;
int& rx = const_cast<int&>(x);
rx++;
cout << x << " and " << rx << endl;
cout << "is &x == &xr: " << (&x==&rx) << endl;

G++ 4.9 的输出是

10 and 11
is &x == &xr: 1

【问题讨论】:

  • 你说过:这是未定义的行为。
  • 你知道“未定义的行为”是什么意思吗?
  • 问题是 to 对象指向相同的内存块并且具有相同的类型直到 cv 限定,但“持有”不同的对象......
  • 是的。这是未定义的行为
  • 查看goo.gl/ANHfS7 以比较编译器和不同优化标志。虽然您应该永远依赖于这种未定义的行为,但了解正在发生的事情确实很有用。

标签: c++ const-cast


【解决方案1】:

编译器(嗯,上周的clang++ 3.7.0)确实优化了代码的“意图”,无论其合法性如何:

    movl    $_ZSt4cout, %edi
    movl    $10, %esi
    callq   _ZNSolsEi
    movq    %rax, %rbx
    movl    $.L.str, %esi
    movl    $5, %edx
    movq    %rbx, %rdi
    callq   _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
    movl    $11, %esi
    movq    %rbx, %rdi
    callq   _ZNSolsEi

与往常一样,值得注意的是,未定义行为的行为确实包括“做你认为它会做的事”,以及“不做你认为它会做的事”,这肯定适用于此。

const_cast 最初是 const 的值是未定义的行为,此时您已经放弃了编译器对“正常行为”的所有权利。现在发生的事情是编译器编写者认为正确的事情 - 如果这意味着该值实际上被放置在只读内存中,那么您的代码将无法成功更新该值。但在这种情况下,它只是将 x 优化为常数 10,而 rx 变为 11 - 因为您实际上并没有用 xrx “做”任何其他事情,这对编译器来说“很好”标准。

【讨论】:

    【解决方案2】:

    这显然是一种未定义的行为,因此,据我了解,问题不应该是它发生的原因,而是它发生的原因。

    我不知道 GCC 如何翻译和优化代码,但我最好的猜测是在 cout 行中,x 被替换为编译时的 const 值(编译器假定为10)。

    看看生成的汇编代码可能会很有趣!

    【讨论】:

    • 当然!有趣的是&amp;x==&amp;rx*(&amp;x)!=*(&amp;rx),所以这是一种解释,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    相关资源
    最近更新 更多