What is the runtime for ostensibly "system languages ​​without overhead"?

In particular, I talk more about C ++ and Rust than others. I don't understand how C ++ has a "runtime" in the sense that Java and C # have a runtime - while Java and C # run on top of a virtual machine with its own encapsulated abstractions and such, I don't understand. how can C ++ have one .

Take virtual tables for C ++ for example. Are we looking at dynamic_cast<type>

part of the functionality of the C ++ environment, or are we talking about the C ++ framework for vtables in general? Can it be considered new

and delete

part of the C ++ runtime? What exactly is lead time?

For example, here we have an article on Rust in its own runtime that describes it as:

The Rust runtime can be viewed as a collection of code that enables services such as I / O, task spawning, TLS, etc. an ephemeral collection of objects that enable programs to perform simple tasks.

But isn't this a function of the standard library or language functions and not the actual runtime? What is this very subtle but existing runtime? Even Bjarne expresses his thoughts that C ++ has "zero abstraction" , but if C ++ has a runtime, doesn't that mean that C ++ really has some kind of "backend" code to orchestrate its own very lightweight but still existing abstractions?

TL; DR: What is a runtime and / or runtime in the context of languages ​​like C ++ and Rust, which are supposedly "zero overhead" and don't have "heavy" executables like Java or C #?

Edit: I suspect I was just missing something about semantics here ...

+3


source to share


1 answer


C ++ requires a few things that are not required in something like C.

For example, this usually comes with some overhead for handling exceptions. While it may not be strictly required, most systems have at least a tiny bit of top-level exception handler to tell you that the program will shut down if an exception was thrown but not found anywhere.

It opens up a question as to whether it matches as a "runtime", but the compiler also generates code to look up the stack and finds a handler for a specific exception when thrown.

On the one hand, it is exceptionally tiny (bordering on negligible) compared to something like a full JVM. On the other hand, it is quite large and complex as to what happens by default in something like the JVM or Microsoft CLR.



As for zero overhead ... well, it depends a little on your point of view. The exception handling code can usually be moved out of the main flow of code, so it does not impose any execution overhead in terms of speed until an exception is thrown. However, it does require additional code, so there can be (often) quite a lot of overhead if you look at the size of the executables. Just taking a quick look at the hello world program, for example, it looks like disabling exception handling reduces the executable size by about 2KB using VC ++.

Admittedly, 2K is not a lot of extra code - on the other hand, it is just something that is added essentially to the most trivial program humanly. For a program that actually does something, this is undoubtedly more.

At the end of the day, it’s not enough that most people have a reason to care, but it still exists.

As for how this is handled, it has to do with a combination of code that is linked to the standard library and compiler-generated code (but the exact details vary by implementation - for example, most 32-bit Windows compilers used by Microsoft Structured Exception Handling (in in this case, the operating system provides some of the code), but for 64-bit Windows I believe they all deal with exception handling on their own (which makes the executables bigger but reduces the overhead in terms of speed).

+3


source







All Articles