With standard and bits

This question was first inspired by the (unexpected) results of this code:

uint16_t   t16 = 0;
uint8_t     t8 = 0x80;
uint8_t t8_res;

t16    = (t8 << 1);
t8_res = (t8 << 1);

printf("t16: %x\n", t16);    // Expect 0, get 0x100
printf(" t8: %x\n", t8_res); // Expect 0, get 0

But it turns out this makes sense:

6.5.7 Bitwise shift operators

Limitations

2 Each operand must be an integer type

Thus, the initially confused string is equivalent to:

t16 = (uint16_t) (((int) t8) << 1);

A bit unintuitive IMHO, but at least clearly defined.

Ok, great, but then we do:

{
uint64_t t64 = 1;
t64 <<= 31;
printf("t64: %lx\n", t64); // Expect 0x80000000, get 0x80000000
t64 <<= 31;
printf("t64: %lx\n", t64); // Expect 0x0, get 0x4000000000000000
}

// edit: after the same argument as above, the following should be equivalent:

t64 = (uint64_t) (((int) t64) << 31);

// hence my confusion / expectation [end_edit]

, , () . / " "? - , ( ?), , :

uint32_t << uint64_t

, int; ?

//edit:

, :

uint32_t t32 = 1;
uint64_t t64_one = 1;
uint64_t t64_res;

t64_res = t32 << t64_one;

//end edit

, , int, integer type, uint64_t .

// :

, . , uint8_t , int ? , int 1, :

{
uint16_t t16 = 0;
uint8_t t8 = 0x80;
uint8_t t8_one = 1;
uint8_t t8_res;

t16 = (t8 << t8_one);
t8_res = (t8 << t8_one);

printf("t16: %x\n", t16);
printf(" t8: %x\n", t8_res);
}

t16: 100
 t8: 0

(t8 < t8_one) , uint8_t ?

-

, ISO/IEC 9899: TC9, WG14/N1124 6 2005 . , - , .

+5
3

. 6.5.7 , " ". , , , . , .

, , :

  3. . - .

6.3.1.1:

  2. : int unsigned int:

  • , int unsigned int.
  • _Bool, int, signed int unsigned int.

int , int; unsigned int. . .

uint8_t , int, int ( , int uint8_t, ).

, , . , "" (, uint64_t int unsigned int, , uint64_t).

uint32_t << uint64_t , , - " - ". :

  • int 33 , uint32_t int, int;
  • int 33 , unsigned int - 32 , uint32_t unsigned int, unsigned int;
  • unsigned int 32 , uint32_t uint32_t.

int unsigned int 32 , (uint32_t unsigned int). int/unsigned int 16 , (uint32_t ).

:

uint32_t t32 = 1;
uint64_t t64_one = 1;
uint64_t t64_res;

t64_res = t32 << t64_one;

2 t64_res. , , uint64_t - , :

uint32_t t32 = 0xFF000;
uint64_t t64_shift = 16;
uint64_t t64_res;

t64_res = t32 << t64_shift;

0xf0000000.

, , , :

C , , int/ unsigned int.

+5

, , :

  • int

uint64_t - .

+7

: ( " ". , . uint8_t , , int, int. uint64_t , int unsigned, , << uint64_t.

: , , int. :) , uint32_t, , , int ( ) ().

<<, , ( ). . () .

+3

All Articles