在每种情况下,由const限定的标识符是否只读存储? 还是会在运行时确定?当我要写入“只读”存储器时,究竟会发生什么和/或什么时候发生。
const char **cpp;
char *p;
const char c = 'A';
cpp = &p;
*cpp = &c;
*p = 0;
这个代码在任何情况下都会修改RO mem吗?或者这样做是因为每次我执行它都不是RO mem? 如果是这样,如果char存储在RO mem中并且我正在执行此代码会发生什么? 行为未定义,甚至不是问题。但是这段代码是可执行的。 所以我的问题是:修改只读内存会发生什么?
答案 0 :(得分:2)
这是未定义的行为,这意味着您无法确定将会发生什么。
并且const
变量不需要位于只读存储器中。
C11 6.7.3类型限定符
如果尝试通过use修改使用const限定类型定义的对象 如果是非const限定类型的左值,则行为未定义。如果是尝试 通过使用左值来引用用volatile限定类型定义的对象 如果使用非volatile限定类型,则行为未定义。
答案 1 :(得分:2)
基本上,它取决于编译器。很可能char会进入堆栈并且不会只读(因此,const
意味着只是混乱类型转换,可执行文件中没有任何内容)。堆栈永远不会只读。
如果您将某些const
定义为全局,则很可能会进入DATA
段,这也不是只读的。所以你将再次全力以赴。虽然我可以想象编译器将所有consts放入一个具有只读访问权限的特殊段中,在这种情况下,您将获得通常的访问冲突/段错误。
此外,您可能有一个聪明的编译器可以优化整个代码并用其值替换const变量名的任何出现,在这种情况下,没有任何关于修改此变量的信息。好吧,很可能编译器会非常聪明地看到&c
来理解变量必须存储在某个地方。
请注意多个最可能和可能。未定义的行为是未定义的行为,因此这个答案应该被理解为我们不知道会发生什么。
答案 2 :(得分:1)
首先,const
并不保证实现使用任何只读内存技术。它只是告诉编译器变量是不可变的。然后,当您打破此不变量时,编译器可以告诉您。编译器可以做其他聪明的事情,比如优化,并使用特殊的存储技术,但这是所有特定于实现的细节。