Fredrik
Fredrik

Reputation: 1457

Integer promotion and right shifting

Considering that for example an unsigned char will always be promoted to an int can I assume that if I don't cast to unsigned char before shifting the result will always be implementation defined?

For example:

unsigned char c = 0x0F;
unsigned int a = c >> 2;

Here c will be promoted to an int before shifting to the right. So the shifting will be implementation defined, depending on the compiler.

The right way would be:

unsigned int a = (unsigned char)c >> 2;

My question being, is this statement true:

Doing any shifting on any datatype smaller than int will be implementation defined if not also cast to unsigned type?

Upvotes: 3

Views: 528

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60127

6.5.7p3 on Bitwise Shift Operations says:

The integer promotions are performed on each of the operands.

If you have a subint type on the left side (or right side, but there it doesn't really matter) of a bitshift operations, it'll be promoted to int.

#include <stdio.h>
int main()
{
    http://port70.net/~nsz/c/c11/n1570.html#6.5.7p3
#define TPSTR(X) _Generic(X,unsigned char: "uchar", int: "int")
    unsigned char c = 0x0F;
    printf("%s\n", TPSTR(c>>2));
    printf("%s\n", TPSTR((unsigned char)c>>2));
    printf("%s\n", TPSTR((unsigned char)c>>(unsigned char)2));
}

compiles and prints int int int.

The result of a right-shift on a signed integer type (int) will only be implementation defined iff the left operand has a negative value:

6.5.7p5:

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

Upvotes: 0

dbush
dbush

Reputation: 224892

The result will always be well defined.

A right shift of a signed type is only implementation defined if the value is negative. This is specified in section 6.5.7p5 of the C standard regarding Bitwise shift operators:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

The value also cannot be negative because integer promotions preserve the sign of the value being promoted. From section 6.3.1.1p3 regarding conversion of integers:

The integer promotions preserve value including sign. As discussed earlier, whether a "plain" char is treated as signed is implementation-defined.

So because the value is guaranteed to be positive, the right shift operation is well defined.

Upvotes: 5

Related Questions