C 取消引用指向常量数据类型的指针
当我做以下事情时-C 取消引用指向常量数据类型的指针,c,pointers,constants,C,Pointers,Constants,当我做以下事情时- const int temp=10; int *ptr= &temp; *ptr=100; 通过这样做,我可以取消引用指向常量int的指针。常量数据变量存储在.rodata(只读内存)中 我怎样才能写信给那个部门?为什么它没有失败 另外,我只得到一个编译时警告:初始化将丢弃指向目标类型的指针中的“const”限定符您确定它在.rodata中吗?此代码 const int temp = 10; int main(void) {
const int temp=10;
int *ptr= &temp;
*ptr=100;
通过这样做,我可以取消引用指向常量int的指针。常量数据变量存储在.rodata(只读内存)中
我怎样才能写信给那个部门?为什么它没有失败
另外,我只得到一个编译时警告:初始化将丢弃指向目标类型的指针中的“const”限定符您确定它在
.rodata
中吗?此代码
const int temp = 10;
int main(void) {
int *ptr = &temp;
*ptr = 100;
}
是否在Linux、GCC 5.2.1上崩溃nm
显示.rodata
中存在的符号temp
但是,
int main() {
const int temp = 10;
int *ptr = &temp;
*ptr = 100;
}
不会崩溃,因为变量具有自动存储持续时间,并且它是在堆栈上分配的,而不是驻留在.rodata
节的只读页中
C11草案n1570,6.7.3第6段: 如果试图通过使用具有非限定类型的左值来修改由限定类型定义的对象,则行为未定义。[……] 当然,未定义的行为意味着: 使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此不作要求 所以事实上,任何事情都可能发生,即使你的程序没有因此而崩溃,它仍然是错误的
无论如何,你得到了警告。每当C编译器发出警告时,作为程序员,您应该将其视为错误(即使通过显式设置
-Werror
),因为它们确实是错误;只有很多旧代码依赖于某些错误行为,这些事实上是错误的东西不能成为真正的错误
请注意,C标准没有说明
int*ptr=&temp代码>是错误的-它本身是完全有效的C,并且只有当您试图通过此ptr
更改temp
时,才会出现未定义的行为。您确定它在.rodata
中吗?此代码
const int temp = 10;
int main(void) {
int *ptr = &temp;
*ptr = 100;
}
是否在Linux、GCC 5.2.1上崩溃nm
显示.rodata
中存在的符号temp
但是,
int main() {
const int temp = 10;
int *ptr = &temp;
*ptr = 100;
}
不会崩溃,因为变量具有自动存储持续时间,并且它是在堆栈上分配的,而不是驻留在.rodata
节的只读页中
C11草案n1570,6.7.3第6段:
如果试图通过使用具有非限定类型的左值来修改由限定类型定义的对象,则行为未定义。[……]
当然,未定义的行为意味着:
使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此不作要求
所以事实上,任何事情都可能发生,即使你的程序没有因此而崩溃,它仍然是错误的
无论如何,你得到了警告。每当C编译器发出警告时,作为程序员,您应该将其视为错误(即使通过显式设置-Werror
),因为它们确实是错误;只有很多旧代码依赖于某些错误行为,这些事实上是错误的东西不能成为真正的错误
请注意,C标准没有说明int*ptr=&temp代码>是错误的-它本身是完全有效的C,并且只有当您试图通过此ptr
更改temp
时,才会出现未定义的行为。int*ptr=&temp代码>违反了约束。如果编译器没有抱怨,那么就找出如何正确调用编译器,这是因为C/C++在处理内存时具有灵活性。如果您确信自己在做什么,那么这种灵活性将对您非常有用,因为您可能会遇到一些分割错误。然而,编译器在提醒/警告您这种灵活性方面做得很好。int*ptr=&temp代码>违反了约束。如果编译器没有抱怨,那么就找出如何正确调用编译器,这是因为C/C++在处理内存时具有灵活性。如果您确信自己在做什么,那么这种灵活性将对您非常有用,因为您可能会遇到一些分割错误。然而,编译器在提醒/警告您这种灵活性方面做得很好。