Hacker Newsnew | past | comments | ask | show | jobs | submitlogin



Thanks, that's interesting. And still, it's artificially constructed, so concerning the point I made (actual logic bugs are more likely) I think it stands.

IMHO this is clearly a compiler bug. Yes, it's technically allowed to do this because calling a NULL function pointer is UB, but nobody wants such an optimization (which is my first point from earlier). If the compiler makes such a decision based on UB, shouldn't it be able to at least issue a warning?

Furthermore, why should this be optimized in the first place? If the user decides to make a function pointer instead of a hard-wired inlineable call, he is aware of the performance implications (which are negligible in 99.9% of the cases). Where function call efficiency matters, nobody ever used a function pointer.

Shouldn't the compiler architecture be able to avoid making this optimization, simply by avoiding propagating the UB? It should simply not say "Calling NULL can never happen". This way it would never make optimizations that make the situation even worse. I think this would even be less optimization code!

Instead, when the UB happens, the programmer should get what he deserves (which is, well, calling NULL, and most likely resulting in a segfault, which is the right thing).

On the other hand, if the compiler can infer the value of a function pointer based on propagation of values alone, I'm fine with hard-coding the address, even though it's probably not worth the effort anyway.


That's a "devirtualization" optimization. Suppose you have a C++ class with a virtual method (or something similar coded in C), which only has a single concrete implementation. Clearly, every place which calls that virtual method through any pointer to that class can only be calling that single concrete implementation, so the compiler can call the function directly instead of through the function pointer, perhaps even inlining the called function.

Yes, that EraseAll example is silly, but how can the optimizer distinguish it from non-silly examples? Perhaps there are other alternative functions which also set that same function pointer, but they were all hidden by some #ifdef; in that case, devirtualizing when there's only one option left will be a performance win, and can expose other optimization opportunities.


> devirtualization

Hmm, shouldn't it be possible to do that in some other way? After all, a virtual function is something different than a function pointer (the vtable holding a function pointer is only an implementation detail, isn't it?).

Anyway, I'd rather not have that optimization. When we don't want to pay a small performance hit, we shouldn't make a virtual function in the first place. It's good to see how advanced optimization tricks can combine in dangerous ways with complicated language features!

> distinguish it from non-silly examples?

Yes, probably not possible. There is a real risk, but non-silly examples are less likely than constructed ones.

> all hidden by some #ifdef

If you do it with the preprocessor, there is no need for function pointers in the first place. Just make a #define instead of a variable.

Thanks again for the example, very interesting!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: