Must &= always be interpreted as an operator?
Asked Answered
V

2

12

I was coding and accidentally left out a space between a constant reference and its default value. I was surprised to see that it came up as an error in Intellisense, so I compiled it, and sure enough, it doesn't work in GCC 4.3.4, 4.5.1, or 4.7.2, and doesn't work in Visual Studio 2012, either.

Here's an equivalent sample that demonstrates the error:

struct S {
    S(const int &= 5){}    
};

int main(){}

This yields the following error in GCC, and similar ones in MSVC:

error: expected ',' or '...' before '&=' token

I presume this is because &= is being treated as an operator, but I don't know exactly what to search for in the standard to find more information about this case. &= just comes up with operator-specfic information.

Being curious, I decided to swap it out for an rvalue reference:

S(int &&= 5){}

Strangely enough, this compiles fine on both GCC 4.7.2 and MSVC, which means that &= isn't always lexically paired as an operator.

Why does it work with an rvalue reference, but not an lvalue reference, and what does the standard have to say on the matter?

Vigilance answered 29/11, 2012 at 20:55 Comment(4)
Just as a side note, S(const int & x= 5){} would work. I think you already know that though. Good question. Waiting forward to an answer.Indigoid
@LuchianGrigore, Yes, it does. That's what I was going for when I mistyped this :)Vigilance
It is not being treated as an operator, it is just different token-wise.Nickynico
The & in &= is a bitwise operator, not a reference qualifier.Remission
E
14

This is generally known as the "principle of longest match", or the "maximal munch". Because && is a valid token and &&= is not (there's no compound-assignment notation for &&), the longest token that &&= starts with is &&; after that's been removed, there's no opportunity for &= to be seen as a single token.

This principle is common to many languages, though there are often exceptions to it. For example, in C++11, >> will be analyzed as > followed by > in a context like std::vector<std::vector<int>>.

Eloiseelon answered 29/11, 2012 at 21:3 Comment(7)
Does this mean we might see an addendum for &= just like we did with >> when used with templates?Vigilance
@Vigilance unlikely since >> was just ugly and annoying, and &= in argument lists would be & = (spaces around =) in any respectable code style.Rossuck
@chris: unlikely, since we still have problems with >>>.Newbill
@chris: I wouldn't expect that, but I really don't know. From what I understand, a major factor motivating the change with >> was that compilers were recognizing it anyway for the sake of giving useful error-messages: so it was already being implemented as a special case, just a special case that didn't work. That doesn't seem to be happening with &=.Eloiseelon
@ruakh, Good point with the compilers treating it specially. It's not much extra work for them to change it if they've already implemented it as well. I guess that situation ultimately occurred much more often than this one would, though.Vigilance
Unused/unnamed rvalue-ref parameter with default value of 5?Holism
@jrok, Eh, technically, this was in my declaration, so it was named in the definition. I just condensed it to what would be a linkable program without the extra code :pVigilance
A
6

The parser just works left to right, regardless of associativity, so in the first example, the first full token it finds is the &=. (At that moment, the parser doesn't check for larger constructs yet, so all it knows is that there's that token there.)

In the second example, the token it finds is &&. Because &&= is not a token!

Absinthism answered 29/11, 2012 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.