引用运算符“&”的结果是什么?关于 const 变量?

发布于 2024-12-15 10:19:44 字数 786 浏览 0 评论 0原文

有人问我如何更改 const 变量的值。

我的明显答案是“指针!”但我尝试了下一段代码,我很困惑......

int main()
{
    const int x = 5;
    int *ptr = (int *)(&x); // "Cast away" the const-ness..
    cout << "Value at " << ptr << ":"<< (*ptr) <<endl;
    *ptr = 6;
    cout << "Now the value of "<< ptr << " is: " << (*ptr) <<endl;
    cout << "But the value of x is still " << x <<endl;
    return 0;
}

输出是:

Value at <some address> :5
Now the value of <same address> is: 6
But the value of x is still 5

现在,我不确定 '&x' 返回的确切内容,但它绝对不是 x 的实际地址,因为x 的值没有改变!

但另一方面,ptr did 在开始时包含 x 的值! 那么,它到底是什么?

编辑用VS2010编译

I was asked how can a value of a const variable can be changed.

My my obvious answer was "pointers!" but I tried the next piece of code and I'm puzzled...

int main()
{
    const int x = 5;
    int *ptr = (int *)(&x); // "Cast away" the const-ness..
    cout << "Value at " << ptr << ":"<< (*ptr) <<endl;
    *ptr = 6;
    cout << "Now the value of "<< ptr << " is: " << (*ptr) <<endl;
    cout << "But the value of x is still " << x <<endl;
    return 0;
}

And the output was:

Value at <some address> :5
Now the value of <same address> is: 6
But the value of x is still 5

Now, I'm not sure exactly what is returned from '&x' but it's definitely not the actual address of x, since the value at x wasn't changed!

But on the over hand, ptr did contain the value of x at the beginning!
So, what is it exactly?

EDIT compiled with VS2010

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

岁吢 2024-12-22 10:19:44

您的程序调用未定义的行为(通过指针写入 const 变量是未定义的行为),因此任何事情都可能发生。话虽如此,这里最可能的解释是为什么您会在特定实现中看到这种行为:

当您执行 &x 时,您确实会获得 x 的地址。当您执行*ptr = 6时,您确实将6写入x的内存位置。但是,当您执行 cout << 时x,您实际上并没有从 x 的内存位置读取数据,因为您的编译器通过在此处将 x 替换为 5 来优化代码。由于xconst,因此编译器可以这样做,因为不存在合法的C++ 程序,这样做会改变程序的行为。

Your program invokes undefined behavior (writing to a const variable through a pointer is undefined behavior), so anything might happen. That being said here's the most likely explanation why you get the behavior you see on your particular implementation:

When you do &x, you do get the address of x. When you do *ptr = 6, you do write 6 to x's memory location. However when you do cout << x, you don't actually read from x's memory location because your compiler optimized the code by replacing x with 5 here. Since x is const the compiler is allowed to do that since there is no legal C++ program in which doing so would change the program's behavior.

往事随风而去 2024-12-22 10:19:44

编译器将x缓存在寄存器中,因此内存中的值发生了变化,但最后的打印输出仍然是相同的。查看生成的程序集(使用 -s 进行编译)。

Compiler caches x in a register, so the value in memory changes, but the last print-out is still the same. Check out generated assembly (compile with -s).

っ〆星空下的拥抱 2024-12-22 10:19:44

首先,这种行为是未定义的。也就是说,可能会发生以下情况:

当您执行此操作时:

int *ptr = (int *)(&x);

5 存储在某处的某个地址。这就是指针似乎工作正常的原因。 (尽管抛弃 const 仍然是未定义的行为)

但是,由于编译器优化,x = 5 只是作为最终打印语句中的文字内联。编译器认为它是安全的,因为 x 被声明为 const

cout << "But the value of x is still " << x <<endl;

这就是为什么你打印出原始值 5。

First of all, this behavior is undefined. That said, here's what's probably going on:

When you do this:

int *ptr = (int *)(&x);

The 5 is stored at some address at somewhere. That's why the pointer seems to work properly. (although casting away the const is still undefined behavior)

However, due to compiler optimizations x = 5 is just inlined as a literal in the final print statement. The compiler thinks it's safe because x is declared const.

cout << "But the value of x is still " << x <<endl;

That's why you print out the original value 5.

勿忘初心 2024-12-22 10:19:44

也许您遇到了代码优化的副作用,请尝试通过禁用所有优化来运行相同的代码,或者检查 asm 生成的代码。我猜编译器正在重用函数中某个注册表中的值,因为他押注于 const,所以即使您实际上正在更改该值,更改后的值也不会正确传播。正如基思在评论中注意到的那样,原因是你正在玩一种未定义的行为。

Maybe you are experiencing a side effect of code optimization, try to run the same code by disabling all optimization, or check at the asm generated code. I guess the compiler is reusing the value it has in some registry along the function since he bet on the const, so even if you are actually changing the value, the changed value is not propagated properly. The reasons for that as Keith noticed in the comemnts, is that you are palying with an undefined behavior.

紧拥背影 2024-12-22 10:19:44

&x 返回的是一个指向 const int 的指针(即 int const*)。现在,指针实际上被实现为保存地址,但指针不是地址,您的示例很好地说明了原因:即使在运行时不存在,指针的类型仍然起着重要作用。

在您的情况下,您正在抛弃 const,从而对编译器撒谎“此指针指向非 const int”。然而,编译器从声明中知道 x 的值不能改变(它被声明为 const),并自由地使用这个事实(并且标准允许这样做:您尝试通过指针更改它)转换为非 const int 是未定义的行为,因此允许编译器执行任何操作)。

What is returned from &x is a pointer to const int (i.e. int const*). Now pointers are inded implemented as holding the address, but pointers are not addresses, and your example shows quite nicely why: The type of the pointer, even though not present at run time, still plays an important role.

In your case, you are casting away the const, and thus lying to the compiler "this pointer points to a non-const int". However the compiler knows from the declaration that the value of x cannot change (it was declared const), and makes freely use of that fact (and the standard allows it: Your attempt to change it through a pointer to non-const int is undefined behaviour and therefore the compiler is allowed to do anything).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文