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_AGE
是90
的另一个名称,编译器已经优化了打印90
std::cout << MAX_AGE << std::endl;
,而无需从内存中查找其值。
MAX_AGE
声明为const int
。使用 c 样式强制转换,您可以删除恒常性,然后继续修改常量值。这是 UB。
这是为什么这是 UB 的一个主要示例:由于MAX_AGE
的恒定性,编译器知道它不会改变,因此可以用文字90
替换它的所有出现。
const
告诉编译器变量MAX_AGE
应存储在内存中相应段的写保护区域中。 有了这些知识,编译器就可以避免重复读取相同的内存位置。换句话说,编译器可能会缓存常量值。这就是为什么您看到MAX_AGE
显示原始值的原因。
无论如何,正如已经提到的,您不应该将编译器与您的实际意图混淆。如果您打算将变量存储在写保护区域中,则不应对其进行修改。
相关文章:
- constexpr构造函数需要常量成员函数时出现问题
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++中的指针和常量问题不大
- 当成员值从指针更改为非指针时,C++常量问题
- 常量公共成员有什么问题?
- 生成提升::hana::set 的常量表达式问题
- Visual Studio 2017 中的 cpprestapi 问题找不到 POST/GET 常量
- 关于在需要常量表达式的上下文中使用的glvalue常量表达式的问题
- public:静态常量字符串声明/初始化问题
- C++继承和"常量"交互的问题
- 在多线程函数中返回共享的常量指针会导致计时问题吗?
- 将 c++ 字符串转换为常量字符 * 时出现问题
- 推导模板化类参数的模板参数:常量问题
- C++:常量减少重复符号问题
- 常量迭代器的问题
- Win32 Atoi 问题无法将参数 1 从 'wchar_t [5]' 转换为常量字符 *
- 常量正确性和shared_ptr,一个设计问题
- 如何解决这个问题?非常量引用必须绑定到左值
- 结构内工会的常量成员的问题
- 常量对象和函数的问题