5 ms·
The C runtime doesn't really show up on a profiler though. It's crawl the init_array then jump to main. Small enough that a lot of people don't notice the C run
by JonChesterfield 2y ago
The C runtime doesn't really show up on a profiler though. It's crawl the init_array then jump to main. Small enough that a lot of people don't notice the C runtime exists at all. Compiling C to efficient machine code is a much easier problem than compiling Go to similar machine code since all the heavy lifting is done by the programmer.
- YZF 2y agoC doesn't really have a "run time". The startup code is optional and I wouldn't really call it a "run time" in the sense that Go has a runtime for managing goroutines and GC. It's not that easy to write Go code with no dynamic memory allocations and no GC pressure. I think it's fair to say "C is faster than Go". It's not purely a function of the language but a combination of factors including the quality of the compiler/optimizer, available libraries, and language features (and their performance cost).
- yxhuvud 2y agoYes it typically does have a runtime. For example, it has persistent structures in memory related to malloc/free, and the manipulation of those most definitely show up when you profile.
- jstimpfle 2y agoIt's a bit funny to call this "runtime" when malloc/free are nothing but library functions.
- yxhuvud 2y agoYes, it is a runtime provided by libc, but how on earth is it not a runtime?
- jgalt212 2y agoMaybe the poster considers a runtime something more similar to a global event loop than a set of global functions.
- yxhuvud 2y agoBut libc is more than a set of global functions - it has a bunch of global state associated with them as well. And manipulation of that is what I consider a runtime.
- jstimpfle 2y agoYou can live entirely without malloc(). You don't need it. You can even allocate memory dynamically without malloc, just call a different API. On Windows, it's typical to use e.g. VirtualAlloc(). So thinking of malloc as runtime seems extremely strange to me. libc is not the only library that has "global state". There is nothing special about it. You don't need libc (yes, some compilers / platforms somewhat expect you to bundle libc). And malloc is not libc, although some of the functionality in libc uses malloc internally / gives you back memory that you are expected to free().
- hnlmorg 2y agoYou can get different standard libraries and runtimes for other languages too. That doesn't mean that their de facto compilation and execution method isn't via a runtime.
- jstimpfle 2y agoCall it what you want then; I will continue to refer to malloc/free as library functions since that's what they are to me -- functions that I can call, and if I don't call them, they don't come haunting me.
- JonChesterfield 2y agoIt certainly does have a runtime and it isn't optional. It's usually in object files starting with crt, e.g. crt1.o. "c-run-time-1.o". That does whatever is necessary to make the machine look like the C world expects. Setting up the stack pointer before jumping to main is important. Arranging for argc/argv to work. Waking init array or section for global constructors. There's also libc which is roughly a pile of more-or-less useful functions, some of them implemented in terms of syscalls. That one is nominally optional. There's probably a compiler runtime involved as well, libgcc or libclang_rt.builtins or similar, which is likely to be cyclically dependent on libc. Compiler-dependent whether that is optional, and thus likely whether libc is optional in practice.
- PhilipRoman 2y agoYou absolutely can write void _start(void) and as long as you finish using exit() everything will work just fine. I've written some super small programs this way (on the order of few kilobytes) which don't interface with system libraries in any way.
- planede 2y agoC code conforming to the ISO C standard generally requires a (very small) runtime.
- JonChesterfield 2y agoThat'll work on some systems and not others. Whatever compiled and linked your C arranged to _start to be at the place the instruction pointer starts from. Setting up your own stack from C is dicey but sometimes the default value for the stack register is usable as-is. I tend to go with ffreestanding and the crt*.o for the platform instead of going from _start directly but sure, you can write whatever startup code your platform wants yourself and link with -nostdlibs or similar. Some platforms are OK with just the address of the entry point burned into an elf. Compiler test code sometimes looks like that.
- jstimpfle 2y agoAny other language can implement the same conventions, and those conventions aren't specified in the C standard but really platform specific.