简体   繁体   中英

Is typecasting a unary operation?

In C, is typecasting a variable/value considered a unary operation?

And to add to this is typecasting an integer value (perhaps before you apply a mask to it) also a unary operation? Let's say I have

((uint64_t)1 << 30 & 0xFFFF0000FFFF0000LL)

Is 1 padded with zeros (up to 64 bits) and then shifted over?

Logically, yes, it's reasonable to think of it as a unary operator since it takes one operand.

But if you look at the way the C standard classifies expressions, unary operators are covered in section 6.5.3, and the cast operator is described separately in section 6.5.4.

There actually is at least one case where the distinction matters.

sizeof unary-expresson

is one of the several forms of unary-expression . If a cast operator (type-name) were treated as a unary operator like the others, then this:

sizeof (int) 42

would be a valid unary expression: 42 would be the operand of the cast operator, which in turn would be the operand of the sizeof unary operator. But in fact it's a syntax error (because sizeof (int) by itself is a valid expression). To avoid that problem, unary operators and the cast operator are defined separately (in effect given different precedences). To write the above while avoiding a syntax error, you need to add parentheses:

sizeof ((int) 42)

Reference: N1570 , the latest freely available draft of the 2011 ISO C standard.

Being a unary operator means nothing more than having exactly one argument. The type parameter doesn't cound as an argument, so the casting operator is unary.

Your second question is related to operator precedence. A cast has the same precedence as other unary operators, which is higher than shifting << which in turn is higher than binary and & .

So your code is equivalent to:

((((uint64_t)1) << 30) & 0xFFFF0000FFFF0000LL)

The C standards do not talk specifically about "unary operations". They have "unary operators" ("-ors" vs "-ions"), and casts are not part of the former as they are listed separately.

Mathematically, however, they are definitely unary: they have one input and one output.

Your question appears not to be about the terminology , though, but rather about the binding : does

(uint64_t)1 << 30

bind as:

((uint64_t)1) << 30

for instance, and then does all that bind together so that the & operation is applied to its result. The answer here is yes, they do. While the standards don't use an operator precedence grammar, you can derive one from the standard grammars, and in such grammars, casts and unary operators are higher precedence than shift operators, which are higher precedence than bitwise operators.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM