c++ - Weird behavior of right shift operator (1 >> 32) -
I recently encountered a strange behavior using correct-shift operators.
The following program:
#include & lt; Cstdio & gt; # Include & lt; Cstdlib & gt; # Include & lt; Iostream & gt; # Include & lt; Stdint.h & gt; Int foo (int a, int b) {back to a & gt; & Gt; B; } Int bar (uint64_t a, int b) {single & gt; & Gt; B; } Int main (Int arc, four ** argv) {std :: cout & lt; & Lt; "Foo (1, 32):" & lt; & Lt; Fu (1, 32) & lt; & Lt; Std :: endl; Std :: cout & lt; & Lt; "Bar (1, 32):" & lt; & Lt; Bar (1, 32) & lt; & Lt; Std :: endl; Std :: cout & lt; & Lt; "1>> 32:" & lt; & Lt; (1> 32) & lt; & Lt; Std :: endl; // alert here std :: cout & lt; & Lt; "(Int) 1>> (Int) 32:" & lt; & Lt; ((Int) 1> (int) 32) & Lt; Std :: endl; // warnings return here EXIT_SUCCESS; }
should be output:
foo (1, 32): 1 // 0 (but I think I'm missing something) Bar (1, 32): 0 1 & gt; & Gt; 32: 0 (Int) 1 & gt; & Gt; (Int) 32: 0
What happens with the foo ()
function? I think the difference between the last 2 lines is that the last two rows are compiled on time. And if I use a 64 bit integer, why does it "work"?
Any light about it will be highly appreciated!
Definitely relates, this is what gives G ++
:
& gt; G ++ -o test test.cpp test.cpp: In the function 'int main (int, char **)': test.cpp: 20: 36: Warning: correct change number & gt; = Width of type test.cpp: 21: 56: Warning: correct change number & gt; = Type Width
This is probably the CPU actually computing
a & gt; & Gt; (B% 32)
in foo
; In the meantime, 1 >> 32 is a continuous expression, so the compiler constantly folds at compile-time, which gives 0 in any way.
The standard (C ++ 98 and sect; 5.8 / 1) states that
the behavior is undefined if the correct operand is negative, or The bits in the promotion are equal to or greater than
foo (1,32)
and1> & Gt; There is no contradiction by giving different results to 32
.
/ P>
& nbsp;
On the other hand, the 64-bit unsigned value was provided to you in bar
, as 64> 32 results are guaranteed should be 1/2 32 = 0. However, if you type
the bar (1, 64);
You can still get 1.
Edit: Logical Correct Change (SHR) a & gt; & Gt; (B 32/64)
x86 / x86-64 (Intel # 253667, page 4-404):
Destination operations can be a register or memory location, calculating an immediate operation The value or CL register can be counting count of 5 bits (or 6-bit if 64-bit mode is in use and REX.W is used). The calculation range is limited from 0 to 31 (or 63 if 64-bit mode and REX.W are used) is provided for counting a special opecode encoding 1. Although
logical rights-shift (LSR) is implemented on ARM (ARM 6 and 7, at least) (ARMISA page A2-6)
(bits (n), bit) emphasizes LSR_C (bits (N) X, integer variation) and GT; 0; Expand_x = zero altitude (X, shift + N); Results = extended_x ; Carry_out = extended_x & lt; Shift-1 & gt ;; Return (results, beer_out);
Where (ARMISA page AppxB-13)
ZeroXand (x, i) = copy ('0', i-Len (x)): X
This guarantees the correct change of ≥32 that zero will be generated. For example, when this code runs on the iPhone, foo (1,32)
0 returns.
It shows that changing 32-bit integers to ≥32 non-portable
Comments
Post a Comment