> You could put a function's definition in every source file that needs it but that's a terrible idea since the definition has to be the same everywhere if you want anything to work. Instead of having the same definition everywhere, we put the definition in a common file and include it where it is necessary. This common file is what we known as a header.<p>In C and C++ parlance "definition" should be "declaration" and "implementation" should be "definition".[1] The terminology is important if you don't want to get confused when learning more about C and C++. This is compounded by the fact that some languages describe these roles in the author's original terms. (Perhaps the author's terminology reflects his own confusion in this regard?)<p>[1] This is indisputable given the surrounding context, but I didn't want to paste 3-4 whole paragraphs.
If anybody is curious about how templates work, there are many ways, but the two most historically popular are:<p>Prelinker:<p>1. Compile each file, noting which templates are needed in a section in the object file<p>2. Have a special program called the "prelinker" run before the linker that reads each .o file, and then somehow instantiates each template (which usually, but not always requires reparsing the C++ file)<p>Weak Symbols:<p>1. When compiling instantiate every needed template, but mark it somehow in the object file as being weak, so that the linker only pulls in one instantiation for each definition.<p>The prelinker used to be more popular, as if you e.g. instantiate the same template in every single file, your compiler does <i>tons</i> more work with the weak symbols approach, <i>but</i> now weak symbols are popular both because they are <i>much</i> simpler to implement and the fact that compilation is usually parallel, while linker is typically not means that walk clock times may even be faster.
The section describing how a function call is made appears to be slightly incorrect.<p>The return value of the `add` function, in most ABI definitions, would be stored in a register. After that, the `main` function may then copy that value to its own space it has reserved on the stack.<p>This is at odds with the description in the article, which seems to describe `add` passing its return value to `main` via the stack.<p>(This is assuming no optimizations - all this would most likely be inlined anyway, with no function call.)
I've been looking for something like this to send to some C++ newbies. This is almost what I need but not exactly.
Is there something similar that explains how libraries work?
"Basically, the compiler has a state which can be modified by these directives. Since every <i>.c file is treated independently, every </i>.c file that is being compiled has its own state. The headers that are included modify that file's state. The pre-processor works at a string level and replaces the tags in the source file by the result of basic functions based on the state of the compiler."<p>I almost sort of get what the author means here but then I don't really. I mean, there is no 'state' for the compiler that is modified by precompiler directives, so this is probably an analogy or simplification he's making here, but I don't really understand how he gets to the mental image of 'compiler state'. Why not just say it like it is: the preprocessor generates long-assed .i (or whatever) 'files' in memory before the actual compiler compiles them, the content of which can be different between compilation units, because preprocessor preconditions might vary between compilation units?
Bit of a side-question, but somewhat related. Is anyone working on "whole program compilation"? I don't mean whole program optimisation, I mean an attempt to read <i>all</i> files for a given target in memory at the same time and then generate all translation units in one go (all in memory? and maybe linking them in memory too?). Clearly, there would be caveats (strange header inclusion techniques relying on macros to modify text of include files would break, gigantic use of memory and so forth), but for those willing to take the risk, presumably this should result in faster builds right?<p>In fact, ideally you'd even generate <i>all</i> binaries for a project in one go but that may be taking it a step too far :-)<p>At any rate, I searched google scholar for any experience reports on this and found nothing. It must have a more technical name I guess...
I don’t think that article’s accurate. At least not anymore. Modern C++ compilers do less while compiling, and much more while linking. This allows them to inline more stuff and apply some other optimizations.<p>VC++ calls that thing “Link-time Code Generation”: <a href="https://docs.microsoft.com/en-us/cpp/build/reference/ltcg-link-time-code-generation?view=vs-2017" rel="nofollow">https://docs.microsoft.com/en-us/cpp/build/reference/ltcg-li...</a><p>LLVM calls it “Link Time Optimization”, pretty similar: <a href="http://llvm.org/docs/LinkTimeOptimization.html" rel="nofollow">http://llvm.org/docs/LinkTimeOptimization.html</a>
I just watched Matt Godbolt's recent talk about the linking process[1]. It's a pretty good talk.<p>[1] <a href="https://www.youtube.com/watch?v=dOfucXtyEsU" rel="nofollow">https://www.youtube.com/watch?v=dOfucXtyEsU</a>
I hope someday the build and linking process could be standardized, but I don't believe it will happen, because many members of the committee come from Microsoft, Google and other tech giant who want to sell their compiler (or give it for free, but still).<p>There are too much Interests and the standardization would kill many of them