Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Employee
183 Views

SHIFT LEFT BY 64 does not result in ZERO

 

#include <iostream>

int main()
{
unsigned long long kk = 64, Mask, i;

//When you use constant to shift left by 64 it always result in Zero but then you use it using variable it //result 1. In debug mode this is 1 all the time but in release mode value outside the loop comes zero //whereas value inside loop become 0. It seems compiler issue

Mask = (0x1ull << 0x40ll);
printf("Out-1 %d\n", Mask);

Mask = (0x1ull << kk);
printf("Out-2 %d\n", Mask);

for (int i = 1; i < 256; i++) {
Mask = 0x1ull << kk;
printf("Loop %d = %d\n", i, Mask);
}
std::cout << "Hello World!\n";
}

0 Kudos
12 Replies
Highlighted
Moderator
162 Views

Hi Murari,

Thanks for reaching out to us!

Could you please provide your system environment details?

OS Version

Compiler details and Version


Thanks & Regards

Goutham


0 Kudos
Highlighted
Moderator
153 Views

This looks like an overflow issue. You can only shift by 63.

Thanks,


0 Kudos
Highlighted
Employee
148 Views

Hi Goutham, are you from compiler team?  

I thought it can be reproduced on all system (in 64 bit mode) but so far I have tested it on my laptop which is Kaby Lake U and I have also tested it on SKX and ICX system. In debug mode this issue is more reproducible than release mode. Sometime in release mode it only happens when this code is inside loop.

Interesting thing is that shift left with constant value works but when you do same using variable than it does not work. 

 

0 Kudos
Highlighted
Employee
147 Views

Sorry here are more detail

OS - Windows 10.

Win Server 2019

 

Used latest compiler 19.x

0 Kudos
Highlighted
Moderator
138 Views

Hi,

Did you see any warning from the compiler? What are the results you get with cl?

Thanks,


0 Kudos
Highlighted
Employee
132 Views

I see only one warning in the very first line where I am using constant value of 64 to shift left . Although it works all the time .

What is cl? I am using visual studio.

Severity Code Description Project File Line Suppression State
Warning C4293 '<<': shift count negative or too big, undefined behavior ConsoleApplication1 c:\users\administrator\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp 13

 

 

0 Kudos
Highlighted
Moderator
129 Views

cl is Microsoft Compiler. From the warning you provided:

1) The warning came from Microsoft compiler not Intel compiler.

2) You have an overflow, undefined behavior.


If you wanted to shift by 64, you should have code as:

unsigned long long kk = 63, Mask, i;

Mask = (0x1ull << 0x3fll);




0 Kudos
Highlighted
New Contributor I
108 Views

I tried this on VC and had to use 

unsigned long long ull0 = 1;
unsigned long long ull1 = (ull0 << 0x3f) << 1;

but I wonder why not use

ull0 = 1;
ull1 = ull0 ^ ull0;

 

0 Kudos
Highlighted
Employee
100 Views

It looks like for 64 bit number you can only shift up to 63 times similarly for 32 bit number you can shift up to 31 bit otherwise result will be undefined.  

0 Kudos
Highlighted
New Contributor I
85 Views

Yep; in C17 the relevant part of the standard is § 6.5.7 ¶ 3:


The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.


C++17 also has a similar passage in § 8.8:


The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

FWIW, I believe UBSan will warn about this.

0 Kudos
Highlighted
Moderator
72 Views

Hi Murari,

Can we close this thread?

Thanks,


0 Kudos
Highlighted
Employee
70 Views

Yes,

 

Thanks for your support.

0 Kudos