Đum*_*lav 1 c pointers constants
我编写了以下代码以测试它是否可以通过指针a修改常量c。我已经在 Clang、VC 和 GCC 编译器中对其进行了测试,并观察到 VC 和 GCC 代码都按我的预期工作,它将 6 打印到标准输出,而当我用 Clang 编译它时,该值没有被修改,而 5打印到标准输出。
#include <stdio.h>
int main(void) {
const int c = 5;
int* a = (int*) &c;
*a = 6;
printf("%d", c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想知道对此是否有任何众所周知的解释,或者它与编译器的内部结构和其他难以分析的东西有关。提前谢谢大家!
是的。它被称为未定义行为。C11 6.7.3p6:
- 如果尝试通过使用具有非 const 限定类型的左值来修改由 const 限定类型定义的对象,则行为未定义。
未定义的行为解释为:
未定义的行为
在使用不可移植或错误的程序结构或错误数据时的行为,本国际标准对此没有强加要求
注意:可能的未定义行为的范围从完全忽略具有不可预测结果的情况,在翻译或程序执行期间以环境特征的文件化方式(有或没有发布诊断消息),到终止翻译或执行(有诊断消息的发布)。
(强调我的)
在未启用优化的情况下编译与购买法拉利并始终仅以一档行驶相同。如果你使用gcc和编译会发生什么-O3?
使用-O3我的 GCC 生成的代码相当于
#include <stdio.h>
int main(void) {
printf("%d", 5);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那么这个程序怎么样:
#include <stdio.h>
int main(void) {
const char *foo = "Hello world!";
char *bar = (char*)foo;
bar[0] = 'C';
printf("%s\n", foo);
}
Run Code Online (Sandbox Code Playgroud)
使用我的 GCC,-O3它崩溃了。但是如果你使用 Clang,它会打印Hello world!......如果你查看程序集 Clang 发现它可以优化为
int main(void) {
puts("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)