I can't name another language for which this is true.
I get that you're hinting at the insane level of undefined behaviour enforcement by compilers, but I don't think it matters all that much once you understand how optimizing compilers work.
I can't name another language for which this is true.
I get that you're hinting at the insane level of undefined behaviour enforcement by compilers, but I don't think it matters all that much once you understand how optimizing compilers work.
It does not. Implicit casting, inlining, volatile, args passed via registers vs stack etc can significantly change what you expect to be generated.
I mean, can you though? After all you won't even have the same output depending on compiler and flags. And of course not all architectures have the same capabilities, so the same code can compile to a various number of instructions depending on the target architecture.
Not to mention things like bitfield access that can result in non-atomic load/stores for a simple `foo->bar = 1;`
I'm not sure in what sense you could say that C operations map 1-to-1 with assembly any more than Rust, C++ or basically any compiled language.
int test(int x, int y) {
return x % y;
}
test: // @test
sdiv w8, w0, w1
msub w0, w8, w1, w0
ret
Surprisingly, assembly doesn't have the remainder instruction, but instead it has a multiply-then-subtract instruction which is not corresponding 1-to-1 to anything in C. Description: The 32-bit two's complement integer in R and Rv1 is divided
by the source operand. The quotient is left in R; the remain-
der in Rv1. Division will be performed so that the remainder
is of the same sign as the dividend. R must be even.
Example: CLR RO
MOV #20001,R1
DIV #2, RO
Before After
(RO) = 000000 (RO) = 010000 Quotient
(R1) = 020001 (R1) = 000001 Remainder
PDP-11 also had ADC and SBC (add/subtract with carry) instructions which weren't (and still aren't) exposed in C either.The code in the comment you replied to is 64-bit ARM assembly.
This is by design, because C was created do deal with disparate processors and OSs. When it was crated it would be difficult and unwise to assume that an integer has size of 2 bytes, for example, since each machine would define its own preferred length.
It was still a bad design. Of course this is in hindsight, but history has taught is it would have been much better if the default was for specific sized integers, with an option to use `uint_fast32_t` or whatever.
But it wasn't, C made all these software tools possible.
English is very popular but you wouldn't say "English is what made all those books possible" would you?