sha*_*oth 11 c++ memory-management const const-correctness undefined-behavior
在C++中,可以在堆上分配const对象:
const Class* object = new const Class();
const_cast<Class*>( object )->NonConstMethod(); // UB
Run Code Online (Sandbox Code Playgroud)
因此,写入对象的尝试将是UB.
我不知道这样的对象将如何与未声明的堆分配对象不同const:
const Class* object = new Class();
Run Code Online (Sandbox Code Playgroud)
我的意思是当我在堆栈上分配一个对象时,它会转到自动存储,这是特定于实现的,所以可能有一些特定const于实现的方法允许以某种特殊方式分配对象,当我写入对象时会产生UB.
然而,每当我使用new编译器时,都需要发出operator new()函数调用,并且该函数不可能做任何不同的事情 - 它只是以统一的方式分配内存,无论const我的代码中是否存在.
一个是如何const堆上分配的对象从非不同的const一个,如何是不确定的行为可能的,如果我尝试修改呢?
它是不同的,因为创建的对象具有不同的类型(const Class而不仅仅是Class),并且它是未定义的行为,因为标准这样说.
这是短版本.没有理由.(如果有的话,反过来就是真的.没有理由让某些东西成为UB.UB是默认状态.只有当某种事情变得明确时才会出现这种情况)
至于它在实践中意味着什么,或者如果你将对象视为非const,它是否真的会导致问题,硬件不太可能做任何不同的事情.const对象显然不会写入某种只读内存(因为这是不可能的),并且一旦分配了对象,它所在的内存页面可能不会被标记为只读.
但是允许编译器假设该对象是const.因此,如果保证对象不变,它可以以合法的方式优化或转换代码,但如果对象在中途被修改则会中断.
它实际上并不是关于如何将对象存储在硬件中.Const或没有const很少会对硬件级别产生影响.但它在类型系统中有所不同,它对编译器如何转换代码产生了影响.
如果你告诉编译器一个对象是const,那么编译器会相信你,并在假设对象是const的情况下生成代码.
对象没有区别。用于引用内存区域的变量(编译时)类型存在差异。
这只是语义摩擦:变量不同,数据位使用的实际内存与常量/易失性无关。
对于描述类似语义摩擦的非常有趣且具有启发性的故事,请参阅埃里克·利珀特(Eric Lippert)一直以来最受欢迎的答案:
以非常量方式处理 const 数据可能会导致未定义行为,因为允许编译器基于const 变量不会更改的知识进行某些优化1。尽管如此,更改它(例如通过const_cast<>)可能会导致错误的结果,因为编译器的假设被主动否定。
1请注意,这volatile对于可以同时修改 const 变量的情况有帮助。您可以看到const“本地”如何不会/不能触及承诺,而volatile说:“不要假设这不会改变,即使它没有被写入此代码段中”。`