Reputation: 6960
I'm using GCC
compiler on Linux.
I want to use 64 bit compiler and build some of my files with -m32
option (32 bit compatibility). I found strange (for me) behavior of compiler.
My code is simple:
int main () {
int test =(((0) & 0x00000000) << (32));
return 0;
}
And for this code I received warning for 32
, 64
and 64
with -m32
compilers:
warning: left shift count >= width of type [enabled by default]
But when I'm trying to compile it from assebmly code
:
.quad (((0) & (0x00000000)) << (32))
I received warning only for 32 bit
compiler:
Warning: shift count out of range (32 is not between 0 and 31)
Why warnings are differ for same code compiled from c
and asm
file for different compilers (32 and 64 bit)?
EDIT:
Where can I find .quad
definition, i mean in code?
Upvotes: 1
Views: 615
Reputation: 86651
In 64 bit mode, gcc uses the LP64 convention. This means that long
and pointers are 64 bits wide, but int
is still only 32 bits wide. In the expression
int test =(((0) & 0x00000000) << (32));
the constants are all assumed to be ints
, because int
is big enough to hold them all, and int
s are always only 32 bits. The result of a shift >= width of the type is UB in C because the behaviour is generally dependent on the underlying architecture's shift instruction.
Suppress the warning by forcing one of the numbers to be 64 bit.
long test =(((0) & 0x00000000L) << (32)); // Still gives a warning with -m32
or
long long test =(((0) & 0x00000000LL) << (32)); // No warning, long long is always 64 bit
Upvotes: 4
Reputation: 476930
In C, the type of the left operand of the shift is int
, which is 32-bit on both platforms in question, so the shift is always undefined behaviour in terms of the C language.
I imagine that in your assembler the operand is either 32 or 64 bit, respectively.
Upvotes: 2