new_c_user
new_c_user

Reputation: 133

warning: left shift count >= width of type [enabled by default]

I have the following piece of code:

long int compute_data_length(unsigned char* buf, int data_offset) {

long int len;

if(!buf)
    return -1;

switch(data_offset) {
    case 2: {
                len = (buf[2] << 8) | buf[3];
            }
            break;
    case 8: {
                len = (buf[2] << 56) |
                      (buf[3] << 48) |
                      (buf[4] << 40) |
                      (buf[5] << 32) |
                      (buf[6] << 24) |
                      (buf[7] << 16) |
                      (buf[8] <<  8) |
                      (buf[9]      );
            }
            break;
    default: len = -1; break;
}
return len;
}

When I compile, I get the following warning:

math_fun.c:240:21: warning: left shift count >= width of type [enabled by default] len = (buf[2] << 56) | ^ math_fun.c:241:27: warning: left shift count >= width of type [enabled by default] (buf[3] << 48) | ^ math_fun.c:242:27: warning: left shift count >= width of type [enabled by default] (buf[4] << 40) | ^ math_fun.c:243:27: warning: left shift count >= width of type [enabled by default] (buf[5] << 32) |

How do I fix the warning?

Upvotes: 1

Views: 7146

Answers (2)

rici
rici

Reputation: 241791

Integer promotions turn buf[2] << 56 into (int)buf[2] << 56 [Note 1], but it is entirely possible that int only has 32 bits and you need it to be an unsigned 64-bit type for the shift to be meaningful.

You're expecting unsigned long to be 64 bits, but it might not be. It would be better to include <stdint.h> and use uint64_t. In any event, you need to explicitly cast the left operands of thE left shift:

((uint64_t)buf[2] << 56) | ...

[Note 1]: It's theoretically possible for unsigned char to be as wide as an int, in which case the integer promotion would be to an unsigned int. But that only happens on unusual architectures.

Upvotes: 5

Deduplicator
Deduplicator

Reputation: 45664

Please learn to read warnings:

math_fun.c:240:21: warning: left shift count >= width of type [enabled by default] len = (buf[2] << 56) | ^

That gives you all the info you need to comprehend your error and how to remedy it:

The type you shift is less than 56 bits long, so shifting 56 bits or more is undefined behavior.
Cast to an appropriately bigger type first.

I hope long fits the bill on your platform, because that's the type of the variable you later assign the result to. int64_t would be guaranteed to be big enough, if it is provided.

While you are at it, consider using only unsigned types there, overflow on signed types is undefined.

Upvotes: 0

Related Questions