【发布时间】:2013-08-06 13:08:10
【问题描述】:
我正在回答question 并制作了这个测试程序。
#include <stdio.h>
int main()
{
volatile const int v = 5;
int * a = &v;
*a =4;
printf("%d\n", v);
return 0;
}
如果没有 volatile 关键字,代码会优化(使用 -O3 apple clang 4.2 编译)var 的变化,它按预期工作并且 const 变量被正确修改。
我想知道一个更有经验的 C 开发人员是否知道标准的一部分是否表明这是不安全的或 UB。
更新: @EricPostpischil 给了我这个标准引用
根据 C 2011 (N1570) 6.7.3 6,程序不得修改其自己使用 const 限定类型定义的对象:“如果尝试通过使用具有非 const 限定类型的左值,行为未定义。”外部代理可以修改具有 volatile 限定类型的对象,根据 6.7.3 7:“具有 volatile 限定类型的对象可能会以实现未知的方式进行修改或具有其他未知的副作用
我的程序违反了第一条规则,但我认为第二条规则可能会使程序免于第一条规则。
更新 2:
具有 volatile 限定类型的对象可能会以实现未知的方式被修改或具有其他未知的副作用。因此,任何引用此类对象的表达式都应严格按照抽象机的规则进行评估,如 5.1.2.3 中所述。此外,在每个序列点,最后存储在对象中的值应与抽象机规定的值一致,除非被前面提到的未知因素修改。134) 构成对具有 volatile 限定类型的对象的访问是实现-定义。
如果您查看此引用,您会看到必须根据某些规则评估 var,我还没有通读 5.1.2.3 部分的所有内容,但我相信这可能会对这个问题有所帮助。
【问题讨论】:
-
我确定这不会编译没有错误。
-
@Devolus 1 警告,除非我在那里留下错字
-
@Devolus 在 c99 标准中,甚至有一个几乎等同于这个的例子,如果我记得哪个,它被称为“可能违反规则”甚至不是“违反规则”规则是,我帮你查一下,但我很抱歉。但我也很困惑,想,这不可能没有任何错误。我试过了......我很想知道...... MSVC2010编译器->没有警告,没有错误clang ->没有错误,1个关于“不合格类型的访问”之类的警告。 gcc 也有 0W/0E。
-
为什么你会认为 6.7.3.7 对 6.7.3.6 有任何影响?通过指针进行的赋值不是“外部代理”或“以实现未知的方式修改”。
标签: c constants volatile undefined-behavior