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.
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...