First, I really don't like the angle taken, then the question of abstraction (why we do it, how) and choices made by languages designers (and variations in their idioms) are so vast that you really can't treat the question through a <1000 signs blog post.
Some quick points:
- You don't code for the machine, you code to be read by another human (possibly you) in the future. I insist, you will be read regularly and frequently. Thus, your code needs to be clear, precise, and concise. This must be the first thing in mind when coding: program what need to be done in a way that a fellow stranger could understand.
- Abstraction is a way to keep a structure of code clear when the interactions become complex and/or abundant. If you can avoid them when still being crystal clear in your code, do it. Direct speaking is always better than convolution.
- The main requirements when you code are often one or two of: quick to develop, easy to maintain, extensible, efficient (you control your big-O and _WORST_ exec times), correct (no bug. at. all.), real time (when X happens, Y is done between n µs and m µs during p ns)
- So, know when performance is a goal, and know when it's not. Choose your language, your techs, your team considering these goals.
- And yeah, C89, C99 and the C++es have a very high overhead of abstraction: clarity, concision, and sometimes performance (all abstractions can't be inlined). Think of it.