将非 class 非数组纯右值转换为 cv 限定类型是否合法?
Is it legal to cast a non-class non-array prvalue to a cv-qualified type?
我正在阅读 value categories,并发现了以下内容(为简洁起见省略了很多):
The following expressions are prvalue expressions:
- a literal (except for string literal), such as 42, true or nullptr;
Properties:
- A non-class non-array prvalue cannot be cv-qualified.
但是...下面的程序编译和运行良好 on ideone.com 并且使用 g++ 5.4.0:
#include <iostream>
int main() {
std::cout << ((const int) 42) << std::endl;
}
我知道编译器会提供扩展,并且可以在遇到未定义行为时执行各种操作。我只是想弄清楚标准的要求。
在N4296中找到相关段落如下:
[expr]
[ ... content omitted ... ]
- If a prvalue initially has the type “ cv T ,” where T is a
cv-unqualified non-class, non-array type, the type of the expression
is adjusted to T prior to any further analysis.
"initially" 这个词让我很吃惊。目前尚不清楚这是否被允许作为另一个表达式的结果,例如用户将非 class 非数组纯右值显式转换为 cv 限定类型(产生另一个纯右值),或者这是否适用只有 "root" 表达式(在本例中为 42
)。
我的问题是,标准是否允许这样的表达式(只是去掉了 cv 限定符),还是不允许这样的表达式(如果相关,这是在哪里强制执行的)?
您应该知道 cppreference 不是规范的。 "Cannot"可能有两种读法:
禁止,阿拉"shall not"
这根本不可能发生,ala invariants
您在文中列出的引述:
If a prvalue initially has the type “ cv T ,” where T is a
cv-unqualified non-class, non-array type, the type of the expression
is adjusted to T prior to any further analysis.
向我建议,cv 限定的纯右值会删除限定条件,就像数组可以衰减为指针一样(澄清一下,这条规则不会发生在转换格式错误的地方)。缺陷 #1261 确实使语言非常明确地说明了在何处发生的事情。
感谢 SanderDeDycker 指出要在其中搜索的标准的相关部分。
我的问题在 N4296 的以下部分得到了回答(强调我的):
[expr.cast]
- The result of the expression (T) cast-expression is of type T . The
result is an lvalue if T is an lvalue reference type or an rvalue
reference to function type and an xvalue if T is an rvalue reference
to object type; otherwise the result is a prvalue. [ Note: if T is a
non-class type that is cv-qualified, the cv-qualifiers are discarded
when determining the type of the resulting prvalue; see Clause 5. —
end note ]
因此我们可以得出结论,(const int) 42
等表达式是完全合法的 C++。
我正在阅读 value categories,并发现了以下内容(为简洁起见省略了很多):
The following expressions are prvalue expressions:
- a literal (except for string literal), such as 42, true or nullptr;
Properties:
- A non-class non-array prvalue cannot be cv-qualified.
但是...下面的程序编译和运行良好 on ideone.com 并且使用 g++ 5.4.0:
#include <iostream>
int main() {
std::cout << ((const int) 42) << std::endl;
}
我知道编译器会提供扩展,并且可以在遇到未定义行为时执行各种操作。我只是想弄清楚标准的要求。
在N4296中找到相关段落如下:
[expr]
[ ... content omitted ... ]
- If a prvalue initially has the type “ cv T ,” where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
"initially" 这个词让我很吃惊。目前尚不清楚这是否被允许作为另一个表达式的结果,例如用户将非 class 非数组纯右值显式转换为 cv 限定类型(产生另一个纯右值),或者这是否适用只有 "root" 表达式(在本例中为 42
)。
我的问题是,标准是否允许这样的表达式(只是去掉了 cv 限定符),还是不允许这样的表达式(如果相关,这是在哪里强制执行的)?
您应该知道 cppreference 不是规范的。 "Cannot"可能有两种读法:
禁止,阿拉"shall not"
这根本不可能发生,ala invariants
您在文中列出的引述:
If a prvalue initially has the type “ cv T ,” where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
向我建议,cv 限定的纯右值会删除限定条件,就像数组可以衰减为指针一样(澄清一下,这条规则不会发生在转换格式错误的地方)。缺陷 #1261 确实使语言非常明确地说明了在何处发生的事情。
感谢 SanderDeDycker 指出要在其中搜索的标准的相关部分。
我的问题在 N4296 的以下部分得到了回答(强调我的):
[expr.cast]
- The result of the expression (T) cast-expression is of type T . The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue. [ Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are discarded when determining the type of the resulting prvalue; see Clause 5. — end note ]
因此我们可以得出结论,(const int) 42
等表达式是完全合法的 C++。