为什么通过指针编译时不能分配 const 初始化

Why can't assign const initialize while compile by pointer

本文关键字:不能分 分配 const 初始化 不能 指针 编译 为什么      更新时间:2023-10-16

我很好奇为什么我的研究结果很奇怪

#include <iostream>
int test()
{
return 0;
}
int main()
{
/*include either the next line or the one after*/
const int a = test(); //the result is 1:1
const int a = 0; //the result is 0:1
int* ra = (int*)((void*)&a);
*ra = 1;
std::cout << a << ":" << *ra << std::endl;
return 0;
}

为什么常量 var 在运行时初始化可以完全更改,但在编译时初始化只会更改指针的 var?

该函数在这里并不那么相关。原则上,您可以为此代码获得相同的输出 (0:1(:

int main() {
const int a = 0;
int* ra = (int*)((void*)&a);
*ra = 1;
std::cout << a << ":" << *ra;
}

aconst int而不是int。您可以执行各种无意义的 c 转换,但修改const对象会调用未定义的行为。

顺便说一下,在上面的示例中,即使对于std::cout << a << ":" << a;编译器,也允许编译器发出打印1:0(或42:3.1415927(的代码。当你的代码有未找到的行为时,任何事情都可能发生。

PS:如果你想研究编译器的内部结构以及它对不是有效 C++ 代码的代码的作用,函数和不同的结果是相关的。为此,最好查看编译器的输出以及它在两种情况下的不同之处(https://godbolt.org/(。

强制转换const变量并更改其值是未定义的行为。如果你尝试,任何事情都可能发生。

无论如何,似乎发生的事情是编译器看到const int a = 0;,并根据优化将其放在堆栈上,但将所有用法替换为 0(因为a不会改变!对于*ra = 1;,存储在内存中的值实际上会发生变化(堆栈是读写的(,并输出该值。

对于const int a = test();,依赖于优化,程序实际上调用函数test()并将值放在堆栈上,在那里它被*ra = 1修改,这也改变了一个。