【问题标题】:Is it possible to change a const data value?是否可以更改 const 数据值?
【发布时间】:2021-12-27 21:36:29
【问题描述】:

有人可以向我解释为什么这段代码不会改变 a 的值吗? 是否可以更改 const 数据值?

案例一:

const int a = 2;
*((int*)&a) = 3;
std::cout << a;

案例2:

const int a = 2;
const_cast<int&>(a) = 3;
std::cout << a;

【问题讨论】:

  • const 数据应保持不变。
  • @ZakiMkn:因为 C++ 不是一种安全的语言。有一些方法可以打破在某些情况下有效但并非在所有情况下都有效的规则。
  • @ZakiMkn 它具有未定义的行为。编译器通常不能对此发出警告。程序员有责任不引起未定义的行为。见stackoverflow.com/questions/2397984/…
  • @ZakiMkn 未定义的行为未定义。也许它现在可以工作,也许它不会,也许它会在未来工作,也许它会让你的电脑变砖,对于会发生什么没有一致的定义。
  • “那么这段代码在做什么?为什么它编译得很好?” 在 cmets 中有这些额外的问题,我倾向于推断 real问题这里是“为什么 C++ 有未定义的行为?”

标签: c++ pointers constants


【解决方案1】:

更改 const 值是未定义的行为。 我建议你不要这样做或编写任何这样做的程序。

【讨论】:

  • 这段代码在做什么呢?为什么编译好?
  • @ZakiMkn 代码以未定义的方式运行。
  • 这涉及到为什么存在未定义行为的讨论。如果你想知道它在做什么的技术答案,你真的要问编译器程序员。我对其所做的最好的猜测是完全忽略更改 const 值的代码行,因为它知道它不应该更改。但这是一个猜测。在那种情况下,编译器编写者可以从字面上做他们想做的任何事情。所以即使这个猜测是正确的,它也不会对每个编译器都是正确的。
  • @Taekahn 我正在寻找的答案,谢谢!
【解决方案2】:

您不能修改常量对象。使用 const_cast 强制转换为非常量引用是可以的,只要您不尝试修改该值。

9.2.9.2 The cv-qualifiers(强调我的)

(4)任何修改尝试 ([expr.ass], [expr.post.incr], [expr.pre.incr]) 一个常量对象 (@987654325 @) 在其生命周期内 ([basic.life]) 导致未定义的行为


您的两个示例也基本相同 - c 样式转换(转换符号)可以解释如下:

7.6.3 Explicit type conversion (cast notation)

(4)
(4.1)const_­cast ([expr.const.cast]),
(4.2) static_­cast ([expr.static.cast]),
(4.3)static_­cast 后跟 const_­cast,
(4.4)reinterpret_­cast ([expr.reinterpret.cast]),或
(4.5)reinterpret_­cast 后跟 const_­cast,
可以使用显式类型转换的强制转换表示法来执行。应用相同的语义限制和行为,[...]。

在您的情况下 (4.1) 适用,因此您的编译器将按以下方式解释 c 样式转换:

const int a = 2;
*((int*)&a) = 3;

// ->

const int a = 2;
*const_cast<int*>(&a) = 3;

基本上,只有当您知道确定给定对象本身不是 const 时,才允许您抛弃 constness 并修改对象,仅你的参考是。

例如:

void foo(int const& ref) {
    // we can cast away const here
    // because we know that a in main is NOT const.
    const_cast<int&>(ref) = 2;
}

int main() {
    int a = 1; // a is not const
    foo(a);

    printf("%d", a); // 2
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 2017-07-24
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多