4 ms·
In general, I agree with you. I just feel the need to expand on a few points. > in C you both control the memory layout of data types very finely True to an e
by derleth 15y ago
In general, I agree with you. I just feel the need to expand on a few points.
> in C you both control the memory layout of data types very finely
True to an extent.
> code maps very directly to an equivalent assembly construct
True but less and less relevant.
Here's where C disconnects you from the processor in the ways that matter most:
1. malloc()/free() are too high-level: You can't control where the allocation subsystem gets your next chunk from, you can't see whether your malloc arena is getting full, you can't see whether you're about to double-free something, and you have no way to recover from a failure to allocate (if that's even possible on your OS).
2. C has no concept of cache; admittedly, assembly usually tries to hide it from you to an extent as well, but assembly language at least has hooks into the cache hardware in the form of memory barriers. C doesn't even have that much.
3. C completely hides the processor status word from you. A minor concern, usually, except in precisely the kind of tight loops people most advocate C for.
4. C has no concept of out-of-order execution or opcode pairing or pipelining in general. Just hope your compiler does.
So, added up, that means C is farther and farther from the hardware all the time. It was reasonably close on the PDP-7 where it was born, was fortuitously even closer to the PDP-11 where it was later implemented, and remained fairly good for a while after, but once you get to dual-core superscalar designs with cache hierarchies and SIMD hardware, you have to rely on the compiler to turn your C into good assembly. Which is, really, a lot like what you do when you write Haskell.