我们可以修改const变量的值吗?

问题描述 投票:6回答:5

来自this article

将变量声明为registerconst的另一种用途是禁止对该变量进行任何非局部更改,即使是通过获取其地址然后强制转换指针也是如此。即使您认为自己永远也不会这样做,一旦将指针((带有const属性)]传递给其他函数,您将永远无法确定这可能是恶意的并在您的脚下更改变量。

我不明白我们如何通过指针修改const变量的值。这不是未定义的行为吗?

const int a = 81;
int *p = (int *)&a;
*p = 42; /* not allowed */
c pointers const read-write
5个回答
11
投票

作者的观点是,使用register存储类声明变量会阻止您获取其地址,因此无法将其传递给可能通过丢弃const来更改其值的函数。

void bad_func(const int *p) {
    int *q = (int *) p;            // casting away const
    *q = 42;                       // potential undefined behaviour
}

void my_func() {
    int i = 4;
    const int j = 5;
    register const int k = 6;
    bad_func(&i);                  // ugly but allowed
    bad_func(&j);                  // oops - undefined behaviour invoked
    bad_func(&k);                  // constraint violation; diagnostic required
}

通过将潜在的UB更改为违反约束条件,就需要进行诊断,并且(必须)对错误进行诊断。在编译时]:

5.1.1.3诊断

1-如果预处理翻译单元或翻译单元,符合标准的实现应产生至少一个诊断消息[...]包含违反任何语法规则或约束的行为,即使该行为也是显式的指定为未定义或实现定义。

6.5.3.2地址和间接操作符约束条件

1-一元&运算符的操作数应为一个左值,该左值指定一个对象,该对象是未用register存储类说明符声明。

请注意,register数组对象上的数组到指针的衰减是未定义的行为,不需要诊断(6.3.2.1:3)。

还请注意,使用C ++中允许的register左值is

的地址,其中register只是一个优化提示(并且不推荐使用)。

3
投票

我们可以修改const变量的值吗?


2
投票

您的代码已编译,但是具有未定义的行为。


1
投票

该代码片段确实调用了未定义的行为。


1
投票

我认为作者也在谈论此案,这是对const的误解:

© www.soinside.com 2019 - 2024. All rights reserved.