1

I've been practicing C today and something came to my mind. Whenever C code is ran, does it load all files needed for execution into memory? Like, does the main.c file and it's header files get copied into memory? What happens if you have a complete C program that takes up 1 GB or something large?

Matthew Schell
  • 599
  • 1
  • 6
  • 19
  • 2
    The .c file isn't involved after the compiler is done. All that's run is the executable program, and whether it's loaded fully depends on the underlying system. (e.g. Microsoft Windows is written in part in C, but I don't have any of those C files/headers on my computer and Microsoft keeps a tight lid on them as they contain trade secrets; all I have is the .exes, .sys files, etc). It could be demand-paged, flashed to a device's EEPROM (for embedded), loaded in its entirety, etc. – nanofarad Jan 09 '21 at 01:42
  • 2
    The question is too broad. The bottom line is there is no one answer, yes there are situations where the whole program is loaded, and no there are situations where the whole program is not loaded in memory all at the same time. – old_timer Jan 09 '21 at 01:44
  • 3
    Does this answer your question? [What happens when a computer program runs?](https://stackoverflow.com/questions/5162580/what-happens-when-a-computer-program-runs) – SuperStormer Jan 09 '21 at 01:57

2 Answers2

4

A C program is first compiled into a binary executable so header files, sources files, etc do not exist anymore at this point... unless you compiled your binary with debugging informations (-g flag).

This is a huge topic. Generally the executable is mapped into what's called virtual memory which allows to address more space than you have available in your computer's memory (through paging). When you will try to access code segments that are not yet loaded, it will create a page fault and the os will fetch what's missing. Compilers will often reorder functions to avoid executing code from random memory locations so you're, most of the time, executing only a small part of your binary.

If you look into specific domains such as HPC or embedded devices the loading policies will likely be different.

Michoumichmich
  • 406
  • 2
  • 8
  • 1
    This is correct for some systems that are commonly used in consumer computing setups. It's worth noting that it's not true for C in general (e.g. a microcontroller may have the whole program stored in a memory attached to the instruction bus, without any paging or swapping; a small computer may have runtime-driven paging but not swapping or implicit OS-assisted demand paging) – nanofarad Jan 09 '21 at 01:50
  • Yes, plus it avoids the overhead of trapping to the kernel (if there's one). This question covers a lot more than just C though – Michoumichmich Jan 09 '21 at 01:57
  • 1
    Thanks Everyone. I forgot for a second that C was a compiled language. I looked into the related question that @SuperStormer sent me and that answered my question. From what I understand, instructions reside in memory and then certain tasks jump to the processor's registers. And when memory needs to be allocated, the heap is for dynamic memory while the stack is for non-dynamic. Once again, thanks for clarifying – Matthew Schell Jan 09 '21 at 04:27
1

C is not interpreted but compiled language.

This means that the original *.c source file is never loaded at execution time. Instead, the compiler will process it once, to produce an executable file containing machine language.

Therefore, the size of source file doesn't directly matter. It may totally be very large if it contains a lot of different use cases, then producing a tiny executable because only the applicable case will be picked at compilation time. However, most of the time, the executable size remains correlated with its source, but it doesn't necessarily means that this will end up in something huge.

Also, included *.h headers file at top of C source files are not actually « importing » a dependence (such as use, require, or import would in other languages). #include statement is only here to insert the content of a file at a given point, but these files usually contain only function prototypes, variable declarations and some precompiler #define clauses, which form the API of an external resource that is linked later to your program.

These external resources are typically other object modules (when you have multiple *.c files within a same project and you don't need to recompile them all from scratch at each time), static libraries or dynamic libraries. These later ones are DLL files under Windows and *.so files under Unix. In this case, the operating system will automatically load the required libraries when you run your program.

Obsidian
  • 3,719
  • 8
  • 17
  • 30