C++ Precedence definitive list [closed]

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-06 13:53:58

Precedence is not a part of the language specification. It is a mnemonic device used by us, humans, to understand the meaning of an expression without recursively analyzing it like an actual parser.

throw, ?: and all assignments in C++ are alternatives in the grammar production assignment-expression, defined as follows

 assignment-expression:
    conditional-expression
    logical-or-expression assignment-operator initializer-clause
    throw-expression

Where conditional-expression is defined as logical-or-expression ? expression : assignment-expression, initializer-clause is another assignment-expression (when it isn't a braced-init-list), and throw-expression is defined as the keyword throw followed by an optional assignment-expression.

In human terms, we describe this as "same precedence, grouping right to left".

To reuse cppreference examples,

e = a < d ? a++ : a = d parses as e = ((a < d) ? (a++) : (a = d))

and false ? 7 : throw 3 parses as false ? 7 : (throw 3), and yes, your example of throw x += 5 parses as throw (x += 5)

Looking at your three sources, the order is essentially the same - C++ Reference groups throw and ?: together with assignment, which is separate in learncpp. Purdue's is much simpler, but also less specific.

Though it might look a bit complicated, I would recommend using learncpp's as a guideline, since it's the most specific. The parenthesis rule is a bit confusing; as a rule of thumb, use them as if they have highest precedence.

On the second part of your question...

(x+1)++;

certainly won't do anything, as (x+1) returns an r-value, which cannot be assigned to by the ++ operator.

(*p)++;

dereferences pointer p, and then increments the variable that it pointed to. Because dereferencing is lower than increment, without the parenthesis, it would dereference p and then increment the pointer, causing undefined behaviour.

I think the reason it's actually written such that postincrement is the same as () is that parenthesis would be done first anyways. Of course, if the () evaluates to an r-value, it will return an error. Preincrement is lower because if needed, the () has to go first. Take, for example,

++(*x);

In this case, x must be dereferenced first before incrementing it.

For your last question about throw, the tables list it as evaluated right-to-left. Your snippet of

throw x += 5;

will evaluate as

throw (x += 5);

It's listed as an operator because it's apparently an expression. Someone else with more knowledge on exception handling could probably explain this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!