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

> In other words: the author's assumption that a C compiler won't optimize `add_twice` in the same way that Rust will is not a guarantee, and assuming that it won't is relying on unspecified behavior.

In C, objects of the same type are presumed to alias unless the compiler can prove otherwise. Unless add_twice is compiled as a file-scoped (i.e. static) function or with equivalent compiler-specific options, the compiler cannot prove that a and b don't alias, and therefore it cannot make such an optimization. This is why C99 added the "restrict" keyword, to tell the compiler that two parameters of the same type do not alias.

This is indirectly why type punning is problematic in C--because C is pessimistic about aliasing, at least for objects of the same type, you normally can't run afoul of aliasing issues as the compiler bares the burden of ensuring safe behavior. But for objects of different types, the compiler can assume they don't alias. When type punning, at the point of usage it appears to the programmer and the compiler that they might alias (because they're the same type), but at some point earlier or later when operating on the original type of the type-punned object(s), the compiler can assume lack of aliasing, generating optimizations that at a distance break the type-safe code. Which is precisely the issue here with Rust FFI, and almost for the same reason--conflict between different aliasing rules in different contexts as Rust presumes lack of aliasing even for objects of the same type. In effect, with Rust FFI you're always type punning arguments passed into a Rust function, which is absolutely a noteworthy issue that absolutely should be addressed by adjusting the default semantics Rust applies to extern'd functions. (C isn't the only language that could run afoul of such aggressive semantics for foreign functions.)



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

Search: