Hacker News new | ask | show | jobs
by simonask 604 days ago
Sure, I mean, my objection is with the pretense that a reasonable calling convention in 2024 could decide to represent void* differently from any other T. It makes total sense that C programmers expect pointers to be (transitively) convertible to/from void, so the fact that they aren't convertible in this way without a trampoline means that the standard contains surprises for even very experienced developers.

I postulate that almost all UB in the wild comes from the Standard diverging from (often very reasonable) expectations, and I see that as a big problem with the standard, at least as long as compilers can't reliably detect the problem at compile-time. (And yes, C++ is even more problematic here.)

I think one of the reasons Zig exists is that it contains far fewer surprises. The reason Rust exists is that it does a much better job at preventing and containing such surprises.

1 comments

Every C compiler I ever used will tell you that void()(void) is not convertible to void ()(char). If people still do it then they are a bit on their own. But how is this then different to Rust's "unsafe"? (of course, there is other UB compiler do not tell you about, that this seems a bad example)
What if the function is written in assembler and takes some pointer to some opaque memory region?

void (*)(char *) and void (*)(void *) and even void\()(struct SomeStruct*) where SomeStruct is declared but never defined could all be correct and reasonable ways to declare that function in a c-header.