|
|
|
|
|
by jcranmer
633 days ago
|
|
> I get that GCC and Clang does all sorts of optimizations, but doesn't unoptimized C map closely to 1:1? Nope. There's actually a number of "optimizations" that get applied to "unoptimized C" code. For example, gcc decides to apply even/odd mathematical function laws to the math library functions even with -O0, and both gcc and clang are very happy to throw "unused" code at -O0 that prevented me from doing jump table shenanigans. C fundamentally has no idea of the distinction between registers and memory, and this is probably the most important distinction in modern assembly languages. It's especially obvious when you get to exotic architectures that have thousands of registers and a relatively thin memory pipe. Making a C compiler get out the assembler that you expected is a lot trickier than you might expect, and when you need exactly some assembly, you'll find that most compiler engineers will tell you "the compiler won't guarantee that, please use assembly" while the people trying to do so often end up spiraling into a rant about how compiler writers are idiots who can't write working compilers because it won't give them the assembly they need. > I thought the thing that was making it not map 1:1 was actually all of the extra features in Rust, like the ADTs and async and all of that. Is that not actually the case? People use a variety of different definitions of "map 1:1" that makes it hard to really answer your question for certain. What you seem to be getting at is the notion that C's ABI is predictable. But there are plenty of C features whose mapping to assembly is as unpredictable as Rust's ADT or async features are: C's bitfields are the most notorious example, but I'd throw in variable arguments, atomics, and the new _BitInt into the mix. Which is to say, if you're an engineer for whom this stuff matters, you'll know how the compiler is going to handle these constructions for your targets of interest, but that's not the same as saying that those constructions will always work the same way on all targets. |
|