Is it legal to cast a non-classical non-array value to the cv class?

I was reading the value categories and came across the following (many omitted for brevity):

The following expressions are prvalue expressions:

  • a literal (other than a string literal), such as 42, true, or nullptr;

Properties:

  • A non-classical non-massive value cannot be cv-qualified.

But ... the following program compiles and works fine on ideone.com and with g ++ 5.4.0:

#include <iostream>

int main() {
    std::cout << ((const int) 42) << std::endl;
}

      

I understand that compilers provide extensions and can do their best if undefined behavior hits. I'm just trying to figure out what the standard mandates mean.

In N4296 I found the following for the relevant passage:

[expression]

[... content omitted ...]

  1. If the original prvalue is of type "cv T", where T is cv-unqualified non-class, non-array type, the expression type is promoted to T. before any further analysis.

The term "initially" is what leaves me. It is unclear if this is allowed as a result of another expression, for example, the user can explicitly specify a non-array for a class with cv qualifications (which gives a different prvalue), or it only applies to the "root" "expression ( 42

in this case).

My question is, does the standard allow such expressions (which just drop the cv qualifiers), or is it forbidden (and where applicable)?

+3


source to share


2 answers


Thanks to SanderDeDycker for pointing out the relevant part of the standard for search.

My question will be answered in the following section N4296 (emphasis mine):



[expr.cast]

  • The result of the expression (T) of the expression-expression is of type T. the result is an lvalue if T is an lvalue reference type, or an rvalue reference to a function type and an x ​​value if T is an rvalue reference to an object type; otherwise, the result is prvalue. [Note: if T is a non-class type that is a cv-qualifier, the cv-qualifiers are discarded when defining the return type; see section 5. - end note]

So we can conclude that type expressions (const int) 42

are perfectly legal C ++.

+1


source


You should be aware that cppreference is not normative. "Can not" can be read in two ways:

  • Forbidden, ala "must not"

  • It just can't be, ala invariants

Quote quoted in the text:



If the original prvalue is of type "cv T", where T is cv-unqualified non-class, non-array type, the expression type is promoted to T. before any further analysis.

suggests me that a qualified prvalue rejects qualification in the same way that arrays can decay into pointers (to clarify, this rule doesn't happen at the point where a cast would be poorly formed). Defect # 1261 makes the language pretty explicit about what happens where.

+1


source







All Articles