Features of the mql5 language, subtleties and tricks - page 304

 
amrali #:

No explanation!

The bug (?!) shows in the intermediate results ONLY (for all bitwise operators).

However, assignment (Num >>= 1) works as expected, (luckily).

All integral sub-types of int are processed internally as int.
 
Alain Verleyen #:
All integral sub-types of int are processed internally as int.
It seems that.. thanks Alain for the explanation.
 
Alain Verleyen #:
All integral sub-types of int are processed internally as int.

The bitwise operators promote small integers (such as char/uchar) to signed ints.  https://stackoverflow.com/a/28142065

The integral promotions of small integers do have side effects to be aware of. In the next example, the uchar/char value can be left shifted more than its width (<< more than 8-bits)

#define PrintExpr(A) Print(#A + " = ", (A), " ["+typename(A)+"]")

void OnStart()
{
  PrintExpr((uchar   (1)) << 15);      // = 32768 [int]
  PrintExpr((ushort  (1)) << 15);      // = 32768 [int]
  PrintExpr((char    (1)) << 15);      // = 32768 [int]
  PrintExpr((short   (1)) << 15);      // = 32768 [int]
}

There also another issue with bitwise operators (Signed types):

When doing bitwise operations, if you want strictly well-defined (according to the standard) results, you generally have to ensure that the values being operated on are unsigned. You can do that either with explicit casts, or by using explicitly unsigned constants (U-suffix) in binary operations.

 
Alain Verleyen #:
All integral subtypes of int are treated internally as int.

Thanks.

 
Apparently because it happens in the 32-bit registers of the processor.
 
  PrintExpr((uchar)   (1 << 15));      // = 0 [uchar]
  PrintExpr((ushort)  (1 << 15));      // = 32768 [ushort].
  PrintExpr((char)    (1 << 15));      // = 0 [char]
  PrintExpr((short)   (1 << 15));      // = -32768 [short]
 
amrali #:

The bitwise operators promote small integers (such as char/uchar) to signed ints.  https://stackoverflow.com/a/28142065

The integral promotions of small integers do have side effects to be aware of. In the next example, the uchar/char value can be left shifted more than its width (<< more than 8-bits)

There also another issue with bitwise operators (Signed types):

When doing bitwise operations, if you want strictly well-defined (according to the standard) results, you generally have to ensure that the values being operated on are unsigned. You can do that either with explicit casts, or by using explicitly unsigned constants (U-suffix) in binary operations.

It's probably better to avoid bitwise operations with char/uchar or short/ushort.

Why would you want to do that anyway ?

If you want to use bits to represent Tick data, just count how much bits you need and use enough int (or long ?) to match them. I don't have time to do it, but could be interesting.