Diving into GCC Internals
gcc-newbies-guide.readthedocs.io
gcc-newbies-guide.readthedocs.io
Summary: headers that use pragma once are tracked using a list resulting in slow uniqueness checks. The performance fix is to use a hash table.
And then for each .c/.cpp file, the compiler has to do the whole rigamarole all over again because modules are too new for everyone to use.
[a]: or worse when you have a full project!
Most translation units have maybe 100 header files or fewer. While a hash map might be O(1) (O(n^2) worst case) and a linked list O(n^2), the overhead of every insertion into a hash map is significantly greater than into a linked list. If you have such a tiny n, a linked list is almost always more time- and space-efficient. Switching to a more inappropriate data structure is more likely to negatively impact the performance of your toolchain.
Of course the best answer is to make the change and collect measurements before and after using a spectrum of data sets, then compare. Don't let me stop you. But remember for that small a number of items bubble sort is usually the fastest, most efficient algorithm. Also remember that looking up a header name at preprocessor time, no matter how slow, will likely not show up on your profile graph when you turn on the optimizer.
My whole point is that something is not adding up with gcc’s implementation. It’s a fail on the authors’ parts, not mine.
$ cd
$ rg --stats 'pragma once' -g '*.{h,hpp}?'
45406 matches
frustratingA preprocessing directive of the form
`#pragma pp-tokens_opt new-line`
where the preprocessing token STDC does not immediately follow pragma in the directive (prior to any macro replacement) causes the implementation to behave in an implementation-defined manner. ...Pragma directives are only part of the C standard if followed by STDC. The ISO C++ standard does not require any pragmas to be supported at all, though most compilers will support at least the ones required by C even in C++ mode.
The issue is that gcc uses a horribly performant method of handling #pragma once when it’s nothing more than a fancy include guard. Clearly they have some quick and optimized way of seeing if a file was #ifdef include guarded, but they created a whole other system based on linked lists for #pragma once.
Since a few years I teach them only to use #pragma once, and the problem has disappeared.
No, it did not.
You have empirically found a wonderful way to teach your students that their errors are their responsibility, and you are wilfully giving it up and sort of spoiling them.
Extrapolating a bit, you are helping them join the idiots who complain about undefined behaviour while proudly showing their horribly wrong code.
I believe that I can teach more interesting ways to catch and prevent errors than that stuff. I find that #ifdef/#define errors are boring and not interesting. The #ifdef/#define errors are due to the archaic way to literally include C/C++ files one into another. By following your reasoning, one would «spoil» their own students and making them «idiots» just by using a language with a proper module system (Rust, Python, Pascal, Ada, Nim…).
Moreover, suggesting to use "#pragma once" means to teach them that you can use the features of the language at your advantage. It is silly to use X if it is error prone when there is Y that is simpler and prevents you from doing that kind of error. I am teaching them that it is worth to dig in the specification of your language and check for possible alternatives of doing X.
I'll give you a hint. Please should stop teaching your students how to write Makefiles just because you want to let them know that a tab at the beginning of a line is different than eight spaces, seriously. Make them learn CMake and use the time in your class to teach more useful stuff about dependencies, feature discoverability, etc. Your students will be eternally grateful.
https://gcc.gnu.org/onlinedocs/gccint/RTL-passes.html
There's really quite a lot of documentation and published papers when you actually look:
https://github.com/gcc-mirror/gcc/blob/751f306688508b08842d0...
GCC: Lots of documentation for backend authors, actively made difficult to being used for frontends for many years (although things have improved dramatically)
GCC’s code style is strange because the original authors wanted to make it look like Lisp for some reason.
While gcc (and in general compiler) plugins are some of the most interesting tech enablers (be it for fuzzing,, static analysis, or runtime checks injection) 'People competently maintaining gcc plugins' (a sect I'm not a part anymore, thank dog) are amongst the most patient, devoted, unsung angels of this world.
It’s also garbage collected so it’s still not “normal” C++ but neither is LLVM.
Not sure about the plugin API, but C++ is basically impossible to use with plugins because it’s so hard to keep ABI contracts, so it might not have changed.
And I’ve seen _p and friends all over the place usually to differentiate between a pointer and, umm, not pointer. I thought it was a C++ism to be honest.
p is short for predicate.
However, when the discussion already mentions "ABI contracts", they're probably referring specifically to the "fragile binary interface problem" (especially regarding member field access), which does not affect all languages that offer inheritance.
As the Wikipedia article mentions, this more specific problem is (confusingly) often referred to just as the "fragile base class problem".
https://en.wikipedia.org/wiki/Fragile_binary_interface_probl...
(It pays for this with extra indirection at runtime, of course: ivar accesses must first look up their runtime-resolved offset.)
Whether that was a good plan is up for debate, but there you go.
I'm wondering why you'd like to know. If it is just for your curiosity, that's very good. If you want to participate in the compiler development effort, hat tip!
But if you are thinking about tuning your code to such an internal detail, please don't! Coding to an implementation, rather than an interface, is never a good idea.
https://dmalcolm.fedorapeople.org/gcc/newbies-guide/memory-m...
Is it? What do you base that on?
I would guess that this hypothesis was true at one time, but is no longer, due to relative memory latencies increasing that mean that the resulting lack of locality becomes a very big problem.
I think this is empirically support by for example this research result, where epsilon collectors are not the highest throughput.
https://users.cecs.anu.edu.au/~steveb/pubs/papers/lbo-ispass...
This decision does force a few other architectural decisions, and as a result has led to a few firey debates.
Most nix users are surprised to learn that nix has no GC. It's unfortunately hard to search for details about this since nix uses the phrase "garbage collection" to describe something it does to the filesystem, rather than memory.
GCC is already basically non-existent in academic research now, although the inner essentials of the compiler are still pretty damn good and is the benchmark for open source compilers, the stuff around the outside is suffering.
https://lwn.net/Articles/582697/
> GCC's developers have actively resisted allowing it to be modularized in a way that would allow GCC's internal representation of a program to be read and used by proprietary compilation tools or optimizers.
Learning about this changed the way I looked at all GNU software.
> Basic things like onboarding and spectating on other people's code being reviewed is pretty hard to do from a mailing list.
Participation is even harder. I made some mistakes when I tried to reply to people on the GPG mailing list because I didn't really understand how mailing lists worked. Thankfully a person made a bug report on the issue tracker.
I still don't fully understand how they work. Many times I thought twice before getting involved in projects because I don't want to risk accidentally emailing people directly instead of the list thread again.
This hasn't been true for at least 10, maybe 15 years.
Mailing list development is very traditional; it's what git was initially designed around, with `format-patch` and `am` commands. People moving to Github and PRs is a generational shift thing, like using TikTok.
Though I know someone who was fired from being GNU libtool maintainer by Stallman because he developed on a Mac.
It means that you had not yet understood the principle behind free software. I'm not defending Stallman's choice, but it is coherent with the philosophy that gave us FSF and GNU.
and this is exactly the place where LLVM shines.