gpt4 book ai didi

c++ - 涉及带有易变变量的表达式的简单语句的正确行为?

转载 作者:可可西里 更新时间:2023-11-01 16:38:13 26 4
gpt4 key购买 nike

考虑以下语句

volatile int a = 7;
a; // statement A
volatile int* b = &a;
*b; // statement B
volatile int& c = a;
c; // statement C

现在,我一直试图在标准中找到一个要点,告诉我编译器在遇到这些语句时的行为方式。我所能找到的只是 A(可能还有 C)给了我一个左值,B 也给了我一个左值:

“§ 5.1.1.8 基本表达式 - 一般”说

An identifier is an id-expression provided it has been suitably declared (Clause 7). [..]
[..] The result is the entity denoted by the identifier. The result is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise.
[..]

“§ 5.3.1 一元运算符”说

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

clang 和 gcc

我用 clang++ 3.2-11 和 g++ 4.7.3 尝试了这个,第一个在 C++11 模式下产生了三个读取,在 C++03 模式下产生了零个读取(输出三个警告),而 g++ 只产生了前两个,明确警告我不会生成第三个。

问题

从标准中引用的行中可以清楚地看出表达式中出现了哪种类型的值,但是:
根据 C++ 标准,哪条语句(A、B、C)应该从 volatile 实体中读取数据?

最佳答案

关于“隐式取消引用”的 G++ 警告来自 gcc/cp/cvt.c 中的代码,它有意不通过引用加载值:

    /* Don't load the value if this is an implicit dereference, or if
the type needs to be handled by ctors/dtors. */
else if (is_volatile && is_reference)

G++ 是有意这样做的,因为如手册 (When is a Volatile C++ Object Accessed?) 中所述,标准并不清楚什么构成对 volatile 限定对象的访问。如那里所述,您需要强制进行左值到右值的转换以强制从 volatile 加载。

Clang 在 C++03 模式下给出了类似解释的警告:

a.cc:4:3: warning: expression result unused; assign into a variable to force a volatile load [-Wunused-volatile-lvalue]
a; // statement A
^
a.cc:6:3: warning: expression result unused; assign into a variable to force a volatile load [-Wunused-volatile-lvalue]
*b; // statement B
^~
a.cc:8:3: warning: expression result unused; assign into a variable to force a volatile load [-Wunused-volatile-lvalue]
c; // statement C
^
3 warnings generated.

G++ 行为和 GCC 手册对于 C++03 似乎是正确的,但 C++11 相对于 C++03 存在差异,由 DR 1054 介绍(这也解释了为什么 Clang 在 C++3 和 C++11 模式下表现不同)。 5 [expr] p10 定义了一个 discarded-value-expression 并表示对于 volatile ,左值到右值的转换应用于id-expression 比如你的语句 A 和 C。左值到右值转换的规范 (4.1 [conv.lval]) 说结果是 glvalue 的值,它构成了对 volatile 的访问。根据 5p10,您的所有三个语句都应该被访问,因此 G++ 对语句 C 的处理需要更新以符合 C++11。我已将其报告为 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59314

关于c++ - 涉及带有易变变量的表达式的简单语句的正确行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20242868/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com