Data type modifier and shift operator

int main(void) { unsigned i = -23; // line 1 short a, b = 0x1; printf("sizeof(short) = %i\n", (int)sizeof(short)); // line 2 a = b << 31; // line 3 printf("i = %i", i); // line 4 printf("i = %u", i); // line 5 return 0; } 

Why doesn't line 1 give any errors when specifying an unsigned type?

Line 2 prints sizeof(short) on my system as 2 bytes. a and b are short integers, therefore, 2 bytes or 16 bits in length. But line 3 does not cause errors. How is a left bit offset of 31 bits possible when the word length is only 16 bits?

Is there any implicit conversion on lines 4 and 5?

I am using the GCC compiler on a 64-bit Mac.

+6
source share
3 answers
  • You will not get an error because a negative integer constant is implicitly converted to an unsigned value, becoming a very large number (MSB is set to one)
  • The value is implicitly converted to int 1,2 is shifted and assigned back; you get all zeros when the number is converted back to short , but this behavior is undefined 3 .
  • In lines 4 and 5 there is no conversion in the sense of C; Regular promotions are applied to pass arguments to variational functions. However, printf reinterprets unsigned as it sings on line 4: the format specifier is the only thing that tells printf about the type of arguments passed to it.

1 Stock before transfer: link .

2 Integer shares: reference .

3 Changing to 30 will be OK, because 2^30 is represented as an int .

+6
source

1) Negative integers are converted to unsigned, adding UINT_MAX + 1 in accordance with point 2 of C99 6.3.1.3 :

  6.3.1.3 Signed and unsigned integers [...] 2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 

2) The operands of the bit shift operators are implicitly converted to int in accordance with C99 6.5.7

 6.5.7 Bitwise Shift Operators 1 Each of the operands shall have integer type. 2 The integer promotions are performed on each of the operands. 3 The type of the result is that of the promoted left operand. 

3) See dasblinkenlight answer.

+2
source

Purpose : the type that you pass to your variable does not say what you can put there, but how the compiler should interpret it. In your case, -23 is "translated" into 32 bits, and then this value is placed in unsigned int (which also has 32 bits) ... (the length of the bits depends on the architecture)

http://en.wikipedia.org/wiki/Two%27s_complement

Shift : when you shift, the bit on one side “leaves”, and on the other side the bit (zeros) must be shifted. You can shift the variable how many times you want.

Printfing . Again, this is not about "conversion", but about the "interpretation" of a number of bits.

0
source

Source: https://habr.com/ru/post/921260/


All Articles