This question is inspired by my attempts to answer another question: Converting decimal/integer to binary - how and why it works the way it does?
The only documentat
The reason is type promotion:
One special case of implicit type conversion is type promotion, where the compiler automatically expands the binary representation of objects of integer or floating-point types. Promotions are commonly used with types smaller than the native type of the target platform's ALU prior to arithmetic and logical operations in order to make such operations possible, or more efficient if the ALU can work with more than one type. C and C++ perform such promotion for objects of boolean, character, wide character, enumeration, and short integer types which are promoted to int, and for objects of type float, which are promoted to double. Unlike some other type conversions, promotions never lose precision or modify the value stored in the object.
So in the following code
var
u8: Byte;
begin
u8 := $ff;
Writeln((u8 shl 7) shr 7);
..
the u8
value is promoted to 32-value before shl
; to fix the result you need explicit type conversion:
Writeln(Byte(u8 shl 7) shr 7);
C++ Standard, Section 4.5 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.
To check if Delphi follows the same convention in type promotion I've written the following application:
var
u8: Byte;
u16: Word;
u32: LongWord;
procedure Test(Value: Integer); overload;
begin
Writeln('Integer');
end;
procedure Test(Value: Cardinal); overload;
begin
Writeln('Cardinal');
end;
begin
u8 := $ff;
Test(u8); // 'Integer'
u16 := $ffff;
Test(u16); // 'Integer'
u32 := $ffffffff;
Test(u32); // 'Cardinal'
Readln;
end.
So I believe there should be no difference between Delphi and C++ here.