const on value是否在数组上有不同的const

时间:2014-01-16 08:16:02

标签: c++ c arrays

似乎const on array将导致用于将数组标记存储在内存中的内存只读。但是为什么const on int不会做同样的事情呢?

代码在这里:

int main(int argc, const char * argv[])
{

    const int vv = 10 ;
    int * p = (int *)&vv ;
    *p = 5 ; // work well

    const int aa[3] = {11, 12, 13} ;
    int * pp = (int *)&aa[1] ;
    *pp = 100 ; // EXC_BAD_ACCESS

    return 0;
}

5 个答案:

答案 0 :(得分:3)

如第7.1.6.1 / 4节所述,第一个和第二个都导致未定义的行为

  

除了可以修改声明为mutable(7.1.1)的任何类成员之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。

事实上,这是其中一种情况,其中C ++风格的演员表(如static_cast),const_castwould have warned you除外。

在C标准中,相同的参考文献在§6.7.3/ 5中进行:

  

如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。

答案 1 :(得分:2)

任何修改const数据的尝试都会导致未定义的行为(UB)。这意味着您的代码似乎“运行良好”,但不能依赖它。

你的例子都是UB。

答案 2 :(得分:2)

如果您在第二次访问时获得了错误的访问权限,则意味着您的编译器不会将初始化程序列表复制到aa,但是aa指向进程的const数据部分(例如,字符串文字的位置)存储)。

正如其他人所指出的那样,更改const会产生未定义的行为。在Visual Studio中,您的代码不会产生任何错误。

当出现对同一个const对象(或C中的数组)的多个引用时,问题浮出水面。更改一个将改变所有这些并且仅在优化的构建中。这种错误很难跟踪。

答案 3 :(得分:1)

看看ISO / IEC 9899 TC3 - >§6.7.3第5部分有说:

  

如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为是未定义的。

所以我猜这对C来说已经足够清楚了,不是吗?

答案 4 :(得分:0)

您的第一部分代码非常正确。您正在使用其引用修改存储在位置的值。这是定义的行为。编译器检查此变量不在表达式的左侧。

使用以下内容使其指向的值保持不变。

const int * p = (int *)&vv