Weird, or just undefined.
Originally Posted by
Draft C99
6.5.7 Bitwise shift operators
Syntax
1
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
Constraints
2
Each of the operands shall have integer type.
Semantics
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.
The first thing, since you're using MinGW (which is a GCC port) is turn up the warning level, and perhaps pay attention to them (if you're already seeing them).
For example
$ gcc -S baz.c
baz.c: In function ‘main’:
baz.c:15: warning: left shift count >= width of type
The second is that with the known constant, the compiler just works out an answer, and in the case with a variable, it actually generates a bunch of code.
Code:
; ret = BITMASK(val); //return 0xFFFFFFFF
; printf("ret: %X\n", ret);
movb $32, 31(%esp)
movzbl 31(%esp), %eax
movl $-1, %edx
movl %edx, %ebx
movl %eax, %ecx
sall %cl, %ebx
movl %ebx, %eax
notl %eax
movl %eax, 24(%esp)
movl $.LC0, %eax
movl 24(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
; ret = BITMASK(32); // return 0xFFFFFFFF
; printf("ret: %X\n", ret);
movl $-1, 24(%esp)
movl $.LC0, %eax
movl 24(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf