Nymokrit
Nymokrit

Reputation: 155

What is the datatype returned by the bitwise complement operator?

I try to understand what exactly the bitwise complement operator in C returns. (Not in terms of 'which value', but in terms of 'which datatype'. I guess I understand how the bit-complement theorethically works, so no need to reexplain that)

Consider the following code:

int main(int argc, char **argv){
   char c = 'A';
   printf("%d, %d\n", sizeof(c), sizeof(~c));
   return 0; 
}

While the first sizeof() returns 1, the latter returns 4 on my machine.

So my question is: Of which datatype is ~c?

I'm working on a 32Bit Linux, would the result change to 8 if I'd work on a 64Bit machine? My best guess so far is, that the bitwise operation is applied to a register and the return value is not casted back to a char value.. And can this behaviour be different for other compilers, or does the C standard define what is returned by ~c?

Upvotes: 14

Views: 1738

Answers (2)

2501
2501

Reputation: 25752

Operator ~, before the actual operation, performs integer promotions1 on the type,
so the type of ~c is implementation defined, either2 int or unsigned int.

Also note that the result of sizeof is the type size_t which should be printed with %zu not %d.


1 (Quoted from ISO:IEC 9899:201x 6.3.1.1 Boolean, characters, and integers 2)
If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions. 58) The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.

2 To clarify why both types and not only int. This is because char may be either signed or unsigned, and it is permitted by the C Standard for unsigned char to not be represented by an int, because the range of the latter could be too small. Had you chosen the type signed char, it could only be promoted to int.

Upvotes: 21

Kerrek SB
Kerrek SB

Reputation: 477040

From 6.5.3.3, Unary arithmetic operators:

Constraints:

The operand of the unary + or - operator shall have arithmetic type; of the ~ operator, integer type; of the ! operator, scalar type.

Semantics:

The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set.) The integer promotions are performed on the operand, and the result has the promoted type.

To summarize: The operand of ~ has an integral type, the operand value is promoted according to the integer promotions, and the type of the result of the expression is that promoted type. (Integer promotions turn anything "smaller" than an int into either an int or an unsigned int, and leave everything else as is.)

Upvotes: 7

Related Questions