6 ms·
There are two levels of deepening your understanding of C. Level 1 is what this article describes: your eyes are opened when you see how various features of C
by haberman 11y ago
There are two levels of deepening your understanding of C.
Level 1 is what this article describes: your eyes are opened when you see how various features of C map naturally onto things that are simple/efficient in hardware. You see a pointer dereference and in your head you think "aha! load instruction." You understand that there is a real difference between "char ch[10]" and "char ch[10] = {0}" -- the latter emits extra instructions to zero out the memory.
Level 2 is when you realize that the optimizer is free to screw with all your intuitive ideas about C -> hardware mapping that you learned about at level 1. You learn that writing correct C means that you need to think in terms of the abstract machine that C defines, and not assume that any specific C statement will translate to the assembly code you expect. You can't think "pointer dereference means load instruction", you have to think "pointer deference reads an object."
There's nothing wrong with level 1, as long as you don't stop there!
- nickpsecurity 11y agoGreat point. It's also worth remembering that optimizations such as floating point at O3 will trade away accuracy for speed. C compilers are willing to give you... the wrong result... but faster than ever! Undefined behavior is another fun line of inquiry. Best to learn about the dark corners and avoid them where possible.
- tspiteri 11y agoNo, you don't get inaccurate floating-point results just by using a higher level of optimization. For example, gcc requires an explicit -ffast-math option for that kind of optimization.
- Narishma 11y agoThere's an explicit compiler flag to get fast but not accurate math and it isn't enabled in any of the -On presets in either gcc or clang.
- nickpsecurity 11y agoMy original source was wrong. Thanks for the correction you two!
- evincarofautumn 11y agoThis is doubly true when dealing with concurrency. You have to consider not only possible interleavings of side effects, but also possible reorderings of loads and stores by the compiler and the CPU. I dunno where I picked it up, but my standard euphemism for writing lock-free code is “juggling knives”.
- agumonkey 11y agoSeriously people would be so happy after investing in learning about interpreters and compilers. When you see a language as an object, data, abstract machine and mapping between them, it clears your mind for good.
- golergka 11y agoIs there a level 3, where you spent enough time with particular compiler to understand and anticipate machine code it outputs?
- haberman 11y agoNot these days, IMO. Optimizers are much too complex for anyone to be able to model them mentally.
- systems 11y agothis reminds me of this quote "Before I learned the art, a punch was just a punch, and a kick, just a kick. After I learned the art, a punch was no longer a punch, a kick, no longer a kick. Now that I understand the art, a punch is just a punch and a kick is just a kick." -- Bruce Lee