<分区>
当我执行以下操作时-
const int temp=10;
int *ptr= &temp;
*ptr=100;
这样做我可以取消引用指向 CONST int 的指针。 const 数据变量存储在 .rodata 中,它是只读内存。
我怎样才能写到那个部分?为什么它不会失败?
附言。我只收到编译时警告:初始化从指向目标类型的指针中丢弃“const”限定符
<分区>
当我执行以下操作时-
const int temp=10;
int *ptr= &temp;
*ptr=100;
这样做我可以取消引用指向 CONST int 的指针。 const 数据变量存储在 .rodata 中,它是只读内存。
我怎样才能写到那个部分?为什么它不会失败?
附言。我只收到编译时警告:初始化从指向目标类型的指针中丢弃“const”限定符
最佳答案
你确定它在.rodata
中吗? ?这段代码
const int temp = 10;
int main(void) {
int *ptr = &temp;
*ptr = 100;
}
在 Linux、GCC 5.2.1 上会崩溃; nm
显示符号 temp
存在于 .rodata
.
但是,
int main() {
const int temp = 10;
int *ptr = &temp;
*ptr = 100;
}
不会崩溃,因为该变量具有自动存储持续时间,并且它是在堆栈上分配的,而不是驻留在 .rodata
的只读页面中部分。
还有 C11 草案 n1570,6.7.3 第 6 段:
If an attempt is made to modify an object defined with a
const
-qualified type through use of an lvalue with non-const
-qualified type, the behavior is undefined. [...]
当然,未定义的行为意味着:
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
所以确实任何事情都可能发生,即使你的程序没有因此而崩溃,它仍然是错误的。
无论如何,您收到了警告。每当 C 编译器发出警告时,作为程序员,您应该将其视为错误(即使通过显式设置 -Werror
),因为它们确实如此;只有很多旧代码依赖于某些不良行为,这些实际上是错误的东西不能成为真正的错误。
请注意,C 标准并未说明 int *ptr = &temp;
是错误的——它本身就是完全有效的 C,并且只有在您尝试更改 temp
时才有效通过这个ptr
发生未定义的行为。
关于c - 取消引用指向 const 数据类型的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37064359/