考虑以下陈述
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 主要表达式 - 一般”说
标识符是一个 id 表达式,只要它已被适当声明(第 7 条)。 [..]
[..] 结果是由标识符表示的实体。结果是
如果实体是函数、变量或数据成员,则左值
否则右值。
[..]
“§ 5.3.1 一元运算符”说
一元 * 运算符执行间接寻址:应用它的表达式应是指向对象类型的指针,或指向函数类型的指针,结果是引用表达式所指向的对象或函数的左值。
铿锵和海湾合作委员会
我用 clang++ 3.2-11 和 g++ 4.7.3 尝试了这个,第一个在 C++11 模式下产生了三个读取,在 C++03 模式下产生了零个读取(输出三个警告),而 g++ 只产生了前两个,明确警告我认为第三个不会生成。
Question
从标准中引用的行可以清楚地看出表达式中产生的是哪种类型的值,但是:
根据 C++ 标准,哪一个语句 (A、B、C) 应该生成对易失性实体的读取?
关于“隐式取消引用”的 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++ 是故意这样做的,因为正如手册中所述(何时访问易失性 C++ 对象?)该标准并不清楚什么构成对 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 定义一个丢弃值表达式并表示对于易失性,左值到右值的转换is应用于id-表达式例如你的陈述A和C。左值到右值转换的规范(4.1 [conv.lval])表示结果是左值的值,它构成了对易失性的访问。根据 5p10,所有三个语句都应该是访问,因此 G++ 对语句 C 的处理需要更新以符合 C++11。我已将其报告为http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59314
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)