gpt4 book ai didi

C++ 对 const 引用参数的依赖没有改变

转载 作者:可可西里 更新时间:2023-11-01 17:40:31 27 4
gpt4 key购买 nike

请考虑以下代码:

void func1(const int &i);
void func2(int i);

void f()
{
int a=12;
func1(a);
func2(a);
}

使用带有 -O3 的 g++ 4.6 编译,我可以看到编译器在函数调用之间重新读取“a”的值。将 a 的定义更改为“const int”,编译器不会这样做,而是简单地将立即值“12”加载到 edi 中。如果 a 不是 const,也是如此,但我将 func1 的签名更改为按值接受。

虽然不是代码生成中的错误,但这仍然是一种奇怪的行为。既然 func1 promise 不改变 a,编译器的代码为什么要根据 a 是否为 const 而改变?

编辑:一些怀疑论者声称我可能读错了代码。上面的代码使用 -S 编译生成以下内容:

_Z1fv:
.LFB0:
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
leaq 12(%rsp), %rdi
movl $12, 12(%rsp)
call _Z5func1RKi
movl 12(%rsp), %edi <-- Rereading a
call _Z5func2i
addq $24, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

将 a 更改为 const 会产生:

_Z1fv:
.LFB0:
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
leaq 12(%rsp), %rdi
movl $12, 12(%rsp)
call _Z5func1RKi
movl $12, %edi <-- Use immediate value
call _Z5func2i
addq $24, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

最佳答案

在 C++ 中,const 实际上只是逻辑常量,而不是物理常量。 func1 可以做一个const_cast 并修改iconst 就像一把枪的安全性 - 你仍然可以射中自己的脚,但不是偶然的。

作为 T.C.和 juanchopanza 在评论中指出,抛弃对象的 constness 并修改它是 UB。引自《笔记》here :

Even though const_cast may remove constness or volatility from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const or to access an object that was declared volatile invokes undefined behavior.

关于C++ 对 const 引用参数的依赖没有改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25029516/

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