我很困惑ANSI规范关于更改声明const
的变量的内容可以通过其地址合法修改。不幸的是,我无法访问C90规范,但却出现了相互矛盾的指示:
关键字const不会将变量变为常量! const的符号 限定符仅表示该符号不能用于赋值。这就是价值 重新通过那个符号;它不会阻止通过修改值 其他一些意味着程序内部(甚至外部)。它只是非常有用 用于限定指针参数,以指示此函数不会更改参数指向的数据,但其他函数可能会更改。 (专家C编程:深C秘密:Peter van der Linden)
如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为未定义。 (http://flash-gordon.me.uk/ansi.c.txt)
我在C99规范中看过后者(n1256.pdf)。
有人可以澄清上述两种观点中的哪一种是真的吗?
编辑:期望C编程实际上给出了一个示例来演示使用指针更改const
变量的能力。
答案 0 :(得分:2)
不知道C90,但是C11包含这个条款,我想这个条款从第一天开始就存在(C11,6.7.3 / 6):
如果尝试通过use修改使用const限定类型定义的对象 对于具有非const限定类型的左值,行为是未定义的。
volatile
- 限定对象也是如此。
答案 1 :(得分:2)
在C90(C89)中与C99类似。
C89 §3.5.3 Type qualifiers
如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为是未定义的。
未定义的行为并不意味着C根本禁止它,只是行为是,没有定义。实际上你的两个陈述都是真的。
答案 2 :(得分:0)
如果您尝试修改const变量,则行为未定义是合乎逻辑的。考虑嵌入式平台,其中代码+常量放在ROM中。在这种情况下,根本不可能改变该值,因为它永远被烧毁。好像一切都在RAM中,它可能会变化。这就是为什么标准在这种情况下说“未定义的行为” - 行为必须依赖于平台和编译器。
声明1和声明2并非真正相互排斥。
答案 3 :(得分:0)
什么声明如:
T const *p; //p has type “pointer to const T
装置?
程序可以使用表达式p来改变p
指定的指针对象的值,但是它不能使用表达式*p
来改变*p
可能的任何对象的值指定。如果程序具有另一个非限定类型的表达式e
,该表达式指定*p
也指定的对象,则程序仍然可以使用e
来更改该对象。
因此,程序可能能够从const-qualified
表达式下更改对象。
答案 4 :(得分:0)
使用指针可以更改const
变量,因为它只是一个内存位置,因此它肯定会接受指针方法所做的更改。
但由于此变量定义为const
,因此其值的更改将调用undefined behaviour。
答案 5 :(得分:0)
是什么让你觉得这两个陈述相互排斥?
const
只是一个类型限定符,它没什么神奇之处。
内存仍然可以通过外部手段或通过规避编译器识别类型限制的能力来改变。第二个陈述只是说试图这样做会产生不明确的结果;它可能会也可能不会改变价值。
我看待它的方式,两种说法都没有任何矛盾。