Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

c++ - Is `f().a[0]` an xvalue?

struct S{
    int a[3] = {1,2,3};
};

S&& f(){return S();}

&f().a;       //[Error] taking address of xvalue (rvalue reference)
&f().a[0];    //ok in GCC 5.1.0 and Clang 3.6.0

S s;
&static_cast<S&&>(s).a;     //[Error] taking address of xvalue (rvalue reference)
&static_cast<S&&>(s).a[0];  //ok in GCC 5.1.0 and Clang 3.6.0

5.7 An expression is an xvalue if it is:

(7.1) — the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,

(7.2) — a cast to an rvalue reference to object type,

(7.3) — a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or

(7.4) — a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.

5.2.1 Subscripting A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T”. The type “T” shall be a completely-defined object type. The expression E1[E2] is identical (by definition) to *((E1)+(E2))<<*t [ Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. —end note ], except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.

So, is f().a[0] an xvalue?

I think f().a[0] should be an xvalue.


[Edit1]

Ignoring &f().a; and &f().a[0]; because 12.2[class.temporary]p5.2

The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement

static_cast<S&&>(s).a is an xvalue(7.2 and 7.3).

" except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise."

So I think static_cast<S&&>(s).a[0] should be an xvalue, but

&static_cast<S&&>(s).a[0]; //ok in GCC 5.1.0 and Clang 3.6.0

Questing:

Am I wrong? If I am wrong, show me an example that subscripting an array results an xvalue.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As far as I can tell you are indeed correct, this looks a "bug", although to be fair this changed recently with CWG defect 1213 which says:

Because the subscripting operation is defined as indirection through a pointer value, the result of a subscript operator applied to an xvalue array is an lvalue, not an xvalue. This could be surprising to some.

and this changed section 5.2.1 [expr.sub] as follows:

A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is an lvalue of type “T.” The type “T” shall be a completely-defined object type.62 The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [Note: see 5.3 [expr.unary] and 5.7 [expr.add] for details of * and + and 8.3.4 [dcl.array] for details of arrays. —end note], except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.

So indeed the result of f().a[0]; and static_cast<S&&>(s).a[0] should be xvalues.

This defect did not have a proposed resolution until December 2012 and clangs defect report support lists the support of that defect report as unknown so most likely the implementers have not gotten to fixing this defect yet.

Update

Filed a clang bug report: Subscript operator applied to an temporary array results in an lvalue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...