It is clear that C++ is much more efficient and that the C++ code compiles directly to machine code whereas in Python it is interpreted.
This is wrong. C++ and Python are programming languages. A programming language is an abstract set of mathematical rules and restrictions. It is neither compiled nor interpreted. It just is.
Any language can be implemented by an interpreter. Any language can be implemented by a compiler. Many languages have both compiled and interpreted implementations. Many modern high-performance language implementations use both interpretation and compilation in the same implementation.
For example, every single currently existing Python implementation uses a compiler:
- CPython has an ahead-of-time compiler that compiles Python source code to CPython byte code.
- PyPy has an ahead-of-time compiler that compiles Python source code to PyPy byte code, then it has another compiler that compiles PyPy byte code to native machine code (or ECMAScript when running in a browser).
- IronPython has an ahead-of-time compiler that compiles Python source code to DLR Trees, then it has another compiler that compiles DLT Trees to .NET CIL byte code, which the .NET runtime then may or may not compile to native machine code.
- GraalPython has an ahead-of-time compiler that compiles Python source code to Truffle ASTs, then Truffle takes over and compiles Truffle ASTs to JVM byte code or native machine code, in the first case, the JVM may then in turn compile the JVM byte code to native machine code.
So, three out of four will eventually compile to native machine code, and even the odd one out still has a compiler.
On the other hand, there are interpreters for C++ such as CINT and Ch. And there is Cling, which is an interpreter based on a JIT compiler based on the Clang ahead-of-time compiler …
I intuitively understand that C++ offers more “control” but what does it mean concretely?
How do you define “control”?
Some people claim that C++ is “closer to the hardware” or that it allows you to have “fine-grained control over how things are laid out in memory”. This is not actually true, however. C++ is specified in terms of an Abstract Machine. There is nothing in the specification guaranteeing that this Abstract Machine corresponds to the real machine that the program is running.
And when you say “closer to the machine”, then what “machine” are you talking about? C++ may be close to a PDP-11, but it is most definitely not close to a Reduceron, and Python is closer than C++ to an Azul Vega 3.
Some people say that C++ has more “control” because all of its default abstractions are “zero overhead”, and any abstractions that are not zero overhead are opt-in. But that is not true either: for example, you cannot opt out of pointers, they are always there. I have worked on a machine that has no pointers, and both C and C++ are very slow on that particular machine, because they have to effectively run inside an interpreter that simulates pointers, and since pointers are most heavily used in high-performance code, that has a huge impact.
Instead of pointers, the machine has a concept of object references in the CPU itself. Unfortunately, there is no native Python implementation on this machine, but there is a native JVM, and on that particular machine, Java was significantly faster than C or C++.
Now, you might say all of those are weird niche machines, surely C++ is close to the PCs we are all actually using? Well, I would argue that this is only technically true, but not for the reason you think it is.
C++ is not “close to the machine” because of anything in C++. Rather, it is “close to the machine” because CPU vendors like Intel and AMD are working very hard to make their CPUs work the way C and C++ expects them to. So, in some sense C++ is not close to the machine, rather the CPU vendors are making the machine close to C++.
Can you give an example of things you can do with C++ but not with python.
I can’t, because there is no such thing.
Both languages are Turing-complete, meaning you can compute any computable function on the natural numbers.
Both languages are “Tetris-complete”, meaning you can process user input, interact with the environment, interact with the OS, interact with libraries written in C or other languages.
And yes, there has been an experimental Operating System written in Python.