繁体   English   中英

C++中指针和常量的小问题

[英]Little problem with pointers and constants in C++

你能向我解释一下这种行为吗? 这里的代码:

int* b = new int;
const int MAX_AGE = 90;
b = (int*)&MAX_AGE;
std::cout << b << std::endl;
std::cout << &MAX_AGE << std::endl;
std::cout << *b << std::endl;
std::cout << MAX_AGE << std::endl;
std::cout << "........." << std::endl;
*b = 2; 
std::cout << *b << std::endl; // HERE I get 2, that's ok
std::cout << MAX_AGE << std::endl; // HERE I still get 90, why?
std::cout << b << std::endl; 
std::cout << &MAX_AGE << std::endl; 

问题是你对编译器撒了谎,而编译器非常擅长报复那些对他们撒谎的人。

具体来说,在这一行中,您告诉编译器MAX_AGE是可变的:

b = (int*)&MAX_AGE;

这是谎言,因为您将MAX_AGE声明为const 接下来发生的事情称为未定义行为 (UB) :在您的代码触发 UB 之后,编译器可以自由地产生任何结果,包括完全无意义的结果。

但是,在您的情况下,对打印的内容有一个很好的解释:知道MAX_AGE90另一个名称,编译器已优化std::cout << MAX_AGE << std::endl; 打印90 ,而无需从内存中查找其值。

MAX_AGE被声明为const int 使用您的 c 样式转换,您可以删除 constness,然后继续修改 const 值。 这是 UB。

这是为什么这是 UB 的一个主要示例:由于MAX_AGE ,编译器知道它不会改变,因此可以用文字90替换它的所有出现。

const告诉编译器变量MAX_AGE应该存储在内存中相应段的写保护区域中。 有了这些知识,编译器就可以避免重复读取同一内存位置的需要。 换句话说,编译器可能会缓存常量值。 这就是为什么您会看到MAX_AGE显示为原始值。

无论如何,正如已经提到的,您不应该将编译器与您的实际意图混淆。 如果您打算将变量存储在写保护区域中,则不应修改它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM