A more or less interesting C/C++ problem occured to me this day:
How do I initialize an integer with one part
without using shifts. For example you have 0xFF
and
you want 0xFFFFFF
.
Normally you would do something like this
int x = 0xFF << 16 | 0xFF << 8 | 0xFF
But how does it work without this runtime computation? And does it help you increase your performance? Of course not, but we'll see.
One could use arrays:
#define FILL(x,t) *(t*)(const unsigned char[]){x,x,x,0}
int main() {
int foo = FILL(0xFF, int);
return 0;
}
This would convert to the following assembly (64bit code):
.main
...
subq $16, %rsp ! reserve space for rbp and foo
movl $._6, %eax ! load address of ._6 (our static array)
movl (%rax), %eax ! dereference rax and save value in eax
movl %eax, -4(%rbp) ! save value of eax in `foo`
...
._6:
.byte -1
.byte -1
.byte -1
.byte 0
If you're wondering why there is -1
and not 255
at the
.byte
directive, the number stands for 0b11111111
whereas
-2
would stand for 0b11111110
and so on.
Comparsion to naive solution
The naive solution:
int foo = 0xFF << 16 | 0xFF << 8 | 0xFF
Compiles to the following assembly (64bit again):
.main:
...
subq $16, %rsp
movl $16777215, -4(%rbp)
movl -4(%rbp), %eax
...
The compiler optimizes the expression so it is a number which will
be put into our variable foo
. This is way better than loading an
address and dereferencing it.
Conclusion
Use shifts, the compiler will optimize them anyway.