4 ms·
Eh, kinda. They are obvious modulo a lot of things, such as what definition of tail call your compiler is using and what optimizations it performs. Your commen
by qsort 6y ago
Eh, kinda. They are obvious modulo a lot of things, such as what definition of tail call your compiler is using and what optimizations it performs.
Your comment piqued my curiosity and I made a little experiment :)
The following function:
int rec(int n) {
if (n < 1) return 0;
return 1 + rec(n - 1);
}
will get TCOd by gcc but not by clang (!!)
I don't know, probably I'm not smart enough for TCO, but I just don't want to work like that. It's a minefield.
- yvdriess 6y agoThat's not a tail recursive call.
- maverwa 6y agoWould you mind sharing the compiler versions and flags used? I tried to look at it in godbolt, but gcc 10.2 -O and clang 11.0 -O look pretty much the same. On the other hand, I know pretty little about C and its compilers ;)
- qsort 6y agoclang 11.0, gcc 7.4, O2. I did that with whatever was already installed on my machines, YMMV.
- CalChris 6y agoHowever, for -O3 on ARMv8, LLVM generates pretty good if slightly inscrutable code [1]: rec: // @rec bic w0, w0, w0, asr #31 ret That's taking the sign bit, replicating it to 32b and then using it as a not'd mask. negative numbers: w0, asr #31 => -1 bic w0, w0, -1 => and w0, w0, 0 => ret 0 positive numbers: w0, asr #31 => 0 bic w0, w0, 0 => and w0, w0, 0xffffffff => ret w0 gcc is also pretty good [2]: rec: cmp w0, 0 csel w0, w0, wzr, gt ret [1] https://godbolt.org/z/q9hM7z https://godbolt.org/z/q9hM7z [2] https://godbolt.org/z/6rbE5e https://godbolt.org/z/6rbE5e
- Hitton 6y agoIt doesn't get TCOd, the compiler simply recognizes what it does and optimizes it. It does literally same thing with the code below. int count(int n) { int res = 0; for (int i=0; i < n; i++) res++; return res; }