5 ms·
I disagree with the author. C is an amazing language but its "lack" of an ABI is, in some ways, a byproduct of the language itself. C essentially sits half a la
by fzliu 5y ago
I disagree with the author. C is an amazing language but its "lack" of an ABI is, in some ways, a byproduct of the language itself. C essentially sits half a layer above assembly and is meant to give the programmer fine-grained control over the processor and memory without requiring intimate knowledge of x86/ARM.
This is why pure C projects can turn into an unmanageable behemoths. This is also why the best way to use C is to use it to implement core algorithms and data structures which can then be called by higher-level languages. Numpy/Scipy did this perfectly and now their use is now ubiquitous within the Python community.
Most software engineers I know who have a background in EE love C, simply because it maps very well to what a processor actually does during execution.
- nrclark 5y ago> Most software engineers I know who have a background in EE love C, simply because it maps very well to what a processor actually does during execution. I agree with this. One thing to note though: C maps onto small CPUs pretty well. It doesn't map directly onto the x86_64 execution model at all. Today's fast CPUs are very different than the abstract machine that C represents. They run all kinds of things out-of-order, do speculative execution, run instructions in parallel, engage in branch prediction, etc. If anything the C execution model is almost a like a little VM that gets mapped onto the core that's running it.
- myrrlyn 5y ago> C is an amazing language [citation needed] > the best way to use C is to use it to implement core algorithms and data structures is this a joke. you literally cannot write containers in C unless you commit to heap-allocating everything and storing it as void* > Most software engineers I know who have a background in EE love C, simply because it maps very well to what a processor actually does during execution. lol. no it absolutely does not. i have a B.S. CpE and have actually built simple processors. the C execution model has nothing to do with how silicon operates, and modern silicon in particular goes to absurd lengths to put up a façade that c programs can use to pretend they're still on a pdp-11 while the processor goes and does other things. easy example: here's a memory address. what happens when you try to read from it
- AdamH12113 5y ago>> Most software engineers I know who have a background in EE love C, simply because it maps very well to what a processor actually does during execution. >lol. no it absolutely does not. i have a B.S. CpE and have actually built simple processors. the C execution model has nothing to do with how silicon operates, and modern silicon in particular goes to absurd lengths to put up a façade that c programs can use to pretend they're still on a pdp-11 while the processor goes and does other things. I'm an EE who's been writing bare-metal firmware for over ten years, and who's helped develop memory subsystems for microcontrollers. What you're saying is certainly true for PC CPUs, but the C execution model works just fine for a Cortex-M or other low-end CPU. No "absurd lengths" are needed; there's a clear relationship between: MOV R2, #0x400 LDR R1, [R2, #5] and: volatile uint32_t *b = (volatile uint32_t *)0x400; uint32_t a = b[5]; >easy example: here's a memory address. what happens when you try to read from it The CPU puts the address on the address lines and sets some control signals appropriately, and the SRAM returns the value at that address on the data lines. (Simplifying, obviously; I'm not going to go dig up an AHB spec.) Cache? What cache? SRAM reads are single-cycle. The flash memory probably has some caching, but that's in the flash subsystem, not the CPU. And a lot of your most important reads and writes will be to memory-mapped registers, which had better not be cached! No, C does not express the details of the instruction pipeline or complex memory subsystems directly in the language. Neither does assembly. C also does not cover every CPU instruction -- that wouldn't be portable at all. That's what inline assembly and compiler intrinsics are for. C strikes a balance between portability and closeness to the hardware while remaining a small language. It does this very well, which is why it has historically been so popular, and still is for some purposes. Not all software is CPU-limited data processing on a 64-bit server.
- kazinator 5y agoAlso the "PDP-11 facade" is needed so that the thing can be programmed in assembly language without the board support people doing bring-up tearing their hair out. A sane assembly language that you can read instruction by instruction to understand the abstract effect is necessary for more than serving as a C compiler target.
- 5y ago