开发者

variables of incompatible width

I am using the following code to simplify assigning large values to specific locations in memory:

int buffer_address =  virtual_to_physical(malloc(BUFFER_SIZE));
    unsigned long int ring_slot = buffer_address << 32 | BUFFER_SIZE;

However, the compiler complains "warning: left shift count >= width of type". But an unsigned long i开发者_JAVA技巧nt in C is 64 bits, so bit-shifting an int (32 bits) to the left 32 bits should yield a 64 bit value, and hence the compiler shouldn't complain. But it does.

Is there something obvious I'm missing, or otherwise is there a simple workaround?


An unsigned long int is not necessarily 64 bits, but for the simplicity let's assume it is.

buffer_address is of type int. Any expression without any "higher" types on buffer_address should return int. Thereby buffer_address << 32 should return int, and not unsigned long. Thus the compiler complains.

This should solve your issue though:

unsigned long ring_slot = ((unsigned long) buffer_address) << 32 | BUFFER_SIZE;

Please note, an unsigned long is not necessarily 64 bits, this depends on the implementation. Use this instead:

#include <stdint.h> // introduced in C99

uint64_t ring_slot = ((uint64_t) buffer_address) << 32 | BUFFER_SIZE;


buffer_address is a (32-bit) int, so buffer_size << 32 is shifting it by an amount greater than or equal to its size.

unsigned long ring_slot = ((unsigned long) buffer_address << 32) | BUFFER_SIZE:

Note that 'unsigned long' need not be 64-bits (it is not on Windows - 32-bit (ILP32) or 64-bit (LLP64); nor it is on a 32-bit Unix machine (ILP32)). To get a guaranteed (at least) 64-bit integer, you need unsigned long long.

There are few machines where int is a 64-bit quantity (ILP64); the DEC Alpha was one such, and I believe some Cray machines also used that (and the Cray's also used 'big' char types - more than 8 bits per char).


The result of the expression on the right side of the = sign does not depend on what it's assigned to. You must cast to unsigned long first.

unsigned long int ring_slot = (unsigned long)buffer_address << 32 | BUFFER_SIZE;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜