【问题标题】:What is memory location modification in C++?什么是 C++ 中的内存位置修改?
【发布时间】:2021-07-04 09:06:12
【问题描述】:

C++ standard 说:

6.9.2.1。如果其中一个修改了内存位置 (6.6.1) 而另一个读取或修改了相同的内存位置,则两个表达式求值会发生冲突。

但是什么算作“修改内存位置”?标准在这句话前只提到了12次“修改”,没有一个是相关的。

例如,

int x = 0;
do_something(&x);
x = 0; // (*)

假设x 在do_something 之后仍然为零,那么(*) 行是否修改x?

【问题讨论】:

  • 任何写入都是“修改”,即使值不变。
  • 您可能引用了较旧的 C++ 标准,请参阅 Working Draft, Standard for Programming Language C++ 该部分似乎不再是 6。
  • @HolyBlackCat 谢谢。它是在标准中明确声明的,还是只是常识?
  • 它仍然存在(注意 - 问题中的引用和标准都指线程数据竞赛)6.9.2.2 Data races
  • 不确定标准是否明确表示,我认为这是常识。

标签: c++ language-lawyer memory-model


【解决方案1】:

我能找到的最相关的规则是(来自最新标准草案的引用)

访问 [defns.access]

⟨执行时动作⟩读取或修改对象的值

[注1:只能访问标量类型的对象。 标量对象的读取在 [conv.lval] 中描述,标量对象的修改在 [expr.ass]、[expr.post.incr] 和 [expr.pre.incr] 中描述。 尝试读取或修改类类型的对象通常会调用构造函数或赋值运算符;这种调用本身并不构成访问,尽管它们可能涉及对标量子对象的访问。 ——尾注]


[intro.object]

C++ 程序中的构造创建、销毁、引用、访问和操作对象。 ... 一个对象在其构建期间([class.cdtor])、整个生命周期和销毁期间([class.cdtor])占用一个存储区域。


[intro.memory]

一个内存位置要么是一个非位域的标量类型对象,要么是所有具有非零宽度的相邻位域的最大序列。

[注 2:语言的各种特性,例如引用和虚函数,可能涉及程序无法访问但由实现管理的额外内存位置。 ——尾注]


[basic.types.general]

算术类型 ([basic.fundamental])、枚举类型、指针类型、指向成员类型 ([basic.compound])、std​::​nullptr_t 和这些类型的 cv 限定版本统称为称为标量类型。 ...

我不会引用突出显示的规则中提到的整个部分,但它们描述了前/后递增/递减和(复合)分配。

该标准似乎也偶尔使用术语“写入”,我认为它与“修改”是同义词。

【讨论】:

    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2017-04-04
    相关资源
    最近更新 更多