Simple questions on shift ops and promotions

G

Glen Able

Just to get my head straight on this...

Firstly, am I right in thinking that right-shifting a signed integer has an
undefined result (i.e. could be implemented as a logical or arithmetic
shift)?

If so, am I also right in assuming that if I right-shift a signed integer by
an unsigned integer, the signed value will be promoted to unsigned and the
shift will be performed as a logical right shift?

Finally, if I specify an int literal, am I right in thinking that it's
treated the same way as any other signed integer, and will be promoted to
unsigned in the same way?

thanks in advance,
glen.
 
A

Attila Feher

Glen said:
Just to get my head straight on this...

Firstly, am I right in thinking that right-shifting a signed integer
has an undefined result (i.e. could be implemented as a logical or
arithmetic shift)?

"If E1 has a signed type and a negative value, the resulting value is
implementation-defined."

This says: nope.
If so, am I also right in assuming that if I right-shift a signed
integer by an unsigned integer, the signed value will be promoted to
unsigned and the shift will be performed as a logical right shift?

As above: it is implementation defined. The docs of your compiler should
tell it.
Finally, if I specify an int literal, am I right in thinking that it's
treated the same way as any other signed integer, and will be
promoted to unsigned in the same way?

The above are exrepts from the standard, talking about right shift operator.
I believe that they answer your questions. As I see no promotions are done
from signed to unsigned. IIRC that is not done just anywhere, only if the
required type is unsigned - which seems not to be true in this case. I
might be wrong, but I think you need that u to make your literal unsigned.
 
J

Jack Klein

"If E1 has a signed type and a negative value, the resulting value is
implementation-defined."

This says: nope.


As above: it is implementation defined. The docs of your compiler should
tell it.

No, you are incorrect here. The type of the result is the type of the
promoted left operand. The type of the right operand (the shift
count) does not enter into the promotion of the left operand (the
value shifted).
 
J

Jack Klein

Just to get my head straight on this...

Firstly, am I right in thinking that right-shifting a signed integer has an
undefined result (i.e. could be implemented as a logical or arithmetic
shift)?

The result of right shifting a signed integer type with a negative
value is implementation-defined, as Attila, said, unless it generates
an invalid value. If it does not generate an invalid value, it is
implementation-defined whether the sign bit is retained as a 1 or is
set to 0. If it does generate an invalid value, then you generate
undefined behavior.
If so, am I also right in assuming that if I right-shift a signed integer by
an unsigned integer, the signed value will be promoted to unsigned and the
shift will be performed as a logical right shift?

No, any promotion of the left hand operand (value shifted) is
completely unaffected by the type of the right hand operand (shift
count). Specifically shifting a value of any signed integer type by
an unsigned shift count does NOT convert the value shifted to
unsigned. If the signed type has lesser rank than int (signed char,
signed short, bool), it will be promoted to signed int, not unsigned
int.
Finally, if I specify an int literal, am I right in thinking that it's
treated the same way as any other signed integer, and will be promoted to
unsigned in the same way?

You are right in thinking that it will be treated the same way as any
other signed integer, but that specifically means that it will NOT be
converted to unsigned just because the second operand (shift count) is
unsigned. If you want to shift an unsigned integer literal, append
'U'.
 
A

Attila Feher

Jack said:
No, you are incorrect here. The type of the result is the type of the
promoted left operand. The type of the right operand (the shift
count) does not enter into the promotion of the left operand (the
value shifted).

Read 5.8/1

"The operands shall be of integral or enumeration type and integral
promotions are performed. The type of the result is that of the promoted
left operand. The behavior is undefined if the right operand is negative, or
greater than or equal to the length in bits of the promoted left operand."

Read: "promoted left operand".

1.) The left operand is promoted with the usual integer promotions.

2.) AFAIK that cannot result in it being promoted to unsigned

3.) I did not tell the type of the shift-count will trigger promotion

4.) I did note that if the signed value is negative one should read the docs

I have however made the mistake that by "signed integer" I have assumed a
negative value there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top