Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise "not" operator in C returns signed result

Tags:

c

linux

gcc

gnu99

Consider this code:

uint16_t a = ~ ( uint16_t ) 0;
int16_t  b = ~ ( int16_t ) 0;
printf (
    "%d %d %d %d\n",
    a  == ~ ( uint16_t ) 0,
    a  == ( uint16_t ) ( ~ ( uint16_t ) 0 ),
    b  == ~ ( int16_t ) 0,
    b  == ( int16_t ) ( ~ ( int16_t ) 0 )
);

The output is:

0 1 1 1

GCC throws a warning about a == ~ ( uint16_t ) 0:

comparison is always false due to limited range of data type [-Wtype-limits]

Why is the bitwise "not" operator trying to return a signed value? How can I prevent that?

like image 929
puchu Avatar asked Dec 15 '22 10:12

puchu


1 Answers

Why bitwise "not" operator is trying to return signed value?

Because no operator works on types smaller than int; smaller types (including uint16_t if int has more than 16 bits) are promoted when used as operands. If all values of the original type are representable by int, as they are here, then the promotion will be to int.

How can I prevent that?

You can't; that's how the language works. You'll have to convert the result of the operator to the type you want, either implicitly as you do when initialising a, or explicitly with a cast. Note that you don't need the cast before applying ~; but for maximum portability, you should stick to unsigned types when doing bitwise logic:

uint16_t a = ~0u;
printf("%d\n", a == (uint16_t)~0u);  // Should print 1
like image 104
Mike Seymour Avatar answered Dec 30 '22 00:12

Mike Seymour