c++ - What is the value category of result yielded from shift operators, bit-wise operators, and sizeof operator? -
shift operators: <<
>>
bit-wise operators: ~
, &
, ^
, |
sizeof operator: sizeof()
per c++ standard (n3797), can confirm ~
yields prvalue (5.3.1/2), not others above.
as far can tell results prvalues speculative. seems under-specified in similar way value categories of operands covered in what value category of operands of c++ operators when unspecified? , does standard mandate lvalue-to-rvalue conversion of pointer variable when applying indirection?.
we can see section 3.10
lvalues , rvalues has following note:
the discussion of each built-in operator in clause 5 indicates category of value yields , value categories of operands expects.
but can see section 5
spells out value category explicitly in few cases. in case of particular question spells out explicitly value category of result &
, ~
.
even though underspecified can find clues point in consistent direction. can make argument operands >>
, <<
, ^
, |
converted prvalues. not dictate value category of result seem exclude result being xvalue per section 5
paragraph 7 has following note:
an expression xvalue if is:
— result of calling function, whether implicitly or explicitly, return type rvalue reference object type,
— cast rvalue reference object type,
— class member access expression designating non-static data member of non-reference type in object expression xvalue, or
— .* pointer-to-member expression in first operand xvalue , second operand pointer data member.
in general, effect of rule named rvalue references treated lvalues , unnamed rvalue references objects treated xvalues; rvalue references functions treated lvalues whether named or not.
i don't see reasonable argument result lvalue leaves prvalue.
so details follows:
both ~
, &
covered section 5.3.1
unary operators paragraph 2 says:
the result of each of following unary operators prvalue.
the shift operators require integral promotions covered in section 5.8
shift operators paragraph 1 says:
the operands shall of integral or unscoped enumeration type , integral promotions performed.
and can see integral promotions require prvalues section 4.5
integral promotions says in every paragraph starts with:
a prvalue of [...]
both ^
, |
require usual arithmetic conversions , both say:
operator applies integral or unscoped enumeration operands
and therefore last clause of usual arithmetic conversions applies says:
otherwise, integral promotions (4.5) shall performed on both operands.59
empirical approach
luc danton has empirical approach determining value category of expression in answer empirically determine value category of c++11 expression?. approach uses following code:
template<typename t> struct value_category { // or can integral or enum value static constexpr auto value = "prvalue"; }; template<typename t> struct value_category<t&> { static constexpr auto value = "lvalue"; }; template<typename t> struct value_category<t&&> { static constexpr auto value = "xvalue"; }; // double parens ensuring inspect expression, // not entity #define value_category(expr) value_category<decltype((expr))>::value
and answer outlines logic follows:
an lvalue expression results in lvalue reference type, xvalue in rvalue reference type, , prvalue in type.
the following examples yield prvalue (see live):
int x = 10, y = 2 ; int &xr = x ; int &yr = y ; std::cout << value_category( x << y ) << std::endl ; std::cout << value_category( 10 << 2 ) << std::endl ; std::cout << value_category( xr << yr ) << std::endl ; std::cout << value_category( x | y ) << std::endl ; std::cout << value_category( 10 | 2 ) << std::endl ; std::cout << value_category( x ^ y ) << std::endl ; std::cout << value_category( 10 ^ 2 ) << std::endl ; std::cout << value_category( sizeof( int ) ) << std::endl ; std::cout << value_category( sizeof( x ) ) << std::endl ;
Comments
Post a Comment