Whilst looking up operator associativity on wikipedia, I noticed that delete
has an associativity of right to left. The source is cited as msdn, I checked it and it comes under group 3 precedence, right to left associativity. So I checked the C++ standard (n4296)
5.3 Unary expressions [expr.unary]
1) Expressions with unary operators group right-to-left
unary-expression: postfix-expression ++ cast-expression -- cast-expression unary-operator cast-expression sizeof unary-expression sizeof ( type-id ) sizeof ... ( identifier ) alignof ( type-id ) noexcept-expression new-expression delete-expression unary-operator: one of * & + - ! ~
What implications does this have? What does delete
have any associativity at all?
Two operator characteristics determine how operands group with operators: precedence and associativity. Precedence is the priority for grouping different types of operators with their operands. Associativity is the left-to-right or right-to-left order for grouping operands to operators that have the same precedence.
The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3 , the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary.
In C, the ternary conditional operator has higher precedence than assignment operators.
As Barry said, precedence is determined by the grammar (and there are a few operators that don't really fit well with the basic idea of precedence so you can only really figure out what happens entirely correctly from the grammar, not a precedence table).
Even if we ignore that, however, the precedence of delete only (at least usually) determines whether a statement is legal/allowed, not what it means. To give a counterexample, with +
and *
, precedence determines that 2 * 3 + 4
yields 10 rather than 14 (i.e., multiplication takes precedence).
In the case of delete
, no value is produced as a result of the delete
statement, so a statement like delete x + y;
simply isn't allowed. It would be parsed as (delete x) + y;
, but since delete x
doesn't produce a value that can be added to anything else, the result is always prohibited (and if you change the operator, that will remain true).
Associativity doesn't really make sense for delete
. In particular, associativity deals with whether something like: a @ b @ c
will be parsed as (a @ b) @ c
or a @ (b @ c)
(where @
is some operator). That's only really meaningful for operators that take two operands though. There's simply no way to combine delete
s in a way that allows you to ask the question(s) that associativity answers.
The C++ standard typically does not define operators in terms of precedence or associativity. It defines them in terms of grammar. From [expr.delete], delete
is used in a delete-expression which is defined as:
delete-expression:
::optdelete
cast-expression
::optdelete []
cast-expression
Where cast-expression is defined in [expr.cast]:
cast-expression:
unary-expression
(
type-id)
cast-expression
And unary-expression is a whole bunch of things defined [expr.unary], that are all unary expressions (increments, decrements, delete
s themselves)
That is, delete *x
is right to-left associative because (delete (*x))
is the only way to parse that expression according to the grammar.
This is also reason that cppreference cites delete
's precedence where it does is a direct consequence of that. For example, delete
is higher than +
because in an expression like this:
delete x+y
x+y
is not a unary-expression, so the only legitimate parsing of the grammar would be (delete x) + y
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With