Can the type difference between constants 32768 and 0x8000 make a difference?

喜夏-厌秋 提交于 2019-12-21 07:10:07

问题


The Standard specifies that hexadecimal constants like 0x8000 (larger than fits in a signed integer) are unsigned (just like octal constants), whereas decimal constants like 32768 are signed long. (The exact types assume a 16-bit integer and a 32-bit long.) However, in regular C environments both will have the same representation, in binary 1000 0000 0000 0000. Is a situation possible where this difference really produces a different outcome? In other words, is a situation possible where this difference matters at all?


回答1:


Yes, it can matter. If your processor has a 16-bit int and a 32-bit long type, 32768 has the type long (since 32767 is the largest positive value fitting in a signed 16-bit int), whereas 0x8000 (since it is also considered for unsigned int) still fits in a 16-bit unsigned int.

Now consider the following program:

int main(int argc, char *argv[])
{
  volatile long long_dec = ((long)~32768);
  volatile long long_hex = ((long)~0x8000);

  return 0;
}

When 32768 is considered long, the negation will invert 32 bits, resulting in a representation 0xFFFF7FFF with type long; the cast is superfluous. When 0x8000 is considered unsigned int, the negation will invert 16 bits, resulting in a representation 0x7FFF with type unsigned int; the cast will then zero-extend to a long value of 0x00007FFF. Look at H&S5, section 2.7.1 page 24ff.

It is best to augment the constants with U, UL or L as appropriate.




回答2:


On a 32 bit platform with 64 bit long, a and b in the following code will have different values:

int x = 2;
long a = x * 0x80000000; /* multiplication done in unsigned -> 0           */
long b = x * 2147483648; /* multiplication done in long     -> 0x100000000 */



回答3:


Another examine not yet given: compare (with greater-than or less-than operators) -1 to both 32768 and to 0x8000. Or, for that matter, try comparing each of them for equality with an 'int' variable equal to -32768.




回答4:


Assuming int is 16 bits and long is 32 bits (which is actually fairly unusual these days; int is more commonly 32 bits):

printf("%ld\n", 32768);  // prints "32768"
printf("%ld\n", 0x8000); // has undefined behavior

In most contexts, a numeric expression will be implicitly converted to an appropriate type determined by the context. (That's not always the type you want, though.) This doesn't apply to non-fixed arguments to variadic functions, such as any argument to one of the *printf() functions following the format string.




回答5:


The difference would be if you were to try and add a value to the 16 bit int it would not be able to do so because it would exceed the bounds of the variable whereas if you were using a 32bit long you could add any number that is less than 2^16 to it.



来源:https://stackoverflow.com/questions/8069516/can-the-type-difference-between-constants-32768-and-0x8000-make-a-difference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!