简体   繁体   中英

Result of bitwise operator in C++

Testing a couple of compilers (Comeau, g++) confirms that the result of a bitwise operator of some "integer type" is an int:

void foo( unsigned char );
void foo( unsigned short );

unsigned char a, b;

foo (a | b);

I would have expected the type of "a | b" to be an unsigned char, as both operands are unsigned char, but the compilers say that the result is an int, and the call to foo() is ambiguous. Why is the language designed so that the result is an int, or is this implementation dependent?

Thanks,

This is in fact standard C++ behavior (ISO/IEC 14882):

5.13/1 Bitwise inclusive OR operator

The usual arithmetic conversions are performed; the result is the bitwise inclusive OR function of its operands. The operator applies only to integral or enumeration operands.

5/9 Usual arithmetic conversions

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions , which are defined as follows:

  • If either operand is of type long double , the other shall be converted to long double .
  • Otherwise, if either operand is double , the other shall be converted to double .
  • Otherwise, if either operand is float , the other shall be converted to float .
  • Otherwise, the integral promotions shall be performed on both operands.
  • ...

4.5/1 Integral Promotions

An rvalue of type char , signed char , unsigned char , short int , or unsigned short int can be converted to an rvalue of type int if int can represent all the values of the source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int .

I think it has to do with int supposedly being the "natural" size for the execution environment to allow for efficient arithmetic (see Charles Bailey's answer ).

I would have expected the type of "a | b" to be an unsigned char, as both operands are unsigned char,

My reading of some beginner C books in past left the impression that bitwise operators were left in the language solely for the purpose of the system programming and generally should be avoided.

The operators are performed by the CPU itself. CPU uses for operands registers (which are surely larger than char) and thus compiler cannot know how much bits of a register would be affected by the operation. To not to loose the full result of the operation, compiler upcasts the result to the proper operation. AFAICT.

Why is the language designed so that the result is an int, or is this implementation dependent?

Bit-level representation of data types is in fact implementation defined. That might be the reason why apparently bit-wise operations are also implementation defined.

Though C99 defines in 6.2.6.2 Integer types how they should appear and behave (and later how bitwise operations should work) the particular chapter gives a lot of freedom to the implementation.

It seems this is the same thing as in Java:

Short and char (and other integers smaller than an int) are weaker types than int. Every operation on these weaker types is therefore automatically unboxed into an int.

If you really want to get a short, you will have to typecast it.

Unfortunately I can't tell you why this was done, but it seems this is a relatively common language decision...

Isn't short the same as short int ? in the same way that long is synonymous with int . eg. a short is an int taking up less memory then a standard int ?

int is supposed to be the natural word size for any given machine architecture and many machines have instructions that only (or at least optimally) perform arithmetic operations on machine words.

If the language were defined without integer promotion, many multistep calculations which could otherwise naturally be mapped directly into machine instructions might have to be interspersed with masking operations performed on the intermediates in order to generate 'correct' results.

Neither C nor C++ ever perform any arithmetic operations on types smaller than int . Any time you specify a smaller operand (any flavor of char or short ), the operand gets promoted to either int or unsigned int , depending on the range.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM