8 ms·
If anyone wants to make an easy but useful improvement to GCC, might I suggest: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58770 https://gcc.gnu.org/bugzilla/
by slavik81 4y ago
If anyone wants to make an easy but useful improvement to GCC, might I suggest: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58770 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58770
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.
- rurban 4y agoThe generated switch statements for large sparse lists should be generated to hash tables, perfect tables even. A not so trivial task.
- deleted 4y ago[deleted]
- colejohnson66 4y agoWait. So gcc uses a linked list? OK, but why? If the whole point of #pragma once is to replace include guards, why would they use something as inefficient as a linked list (O(n^2) for this situation[a]) for that, but something quicker for include guards? That’s nonsense! 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!
- bregma 4y agoBasic CS fail. 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.
- LadyCailin 4y agoI’m pretty sure I read something on HN the other day that showed that a linked list is almost always a bad choice, even for small values, due to memory locality issues.
- deleted 4y ago[deleted]
- colejohnson66 4y agoRegardless of what’s better, my comment was more about how they have a profiled and optimized method for include guards, but threw it all away for #pragma once. If performance doesn’t matter because the optimizer is worse, then why’d they optimize include guards? My whole point is that something is not adding up with gcc’s implementation. It’s a fail on the authors’ parts, not mine.
- kevin_thibedeau 4y ago#pragma once isn't needed for GCC anyway. It recognizes include guards and doesn't reparse headers that have already been processed.
- colejohnson66 4y agoThat’s not an argument; every major C compiler recognizes include guards, and every standards compliment C compiler supports them. The whole point of #pragma once is so you don’t have to use them and worry if you have naming collisions. 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.
- ziotom78 4y agoI teach a C++ class, and I can assure you that one of the most frequent errors I see in students' codes is to copy-and-paste a header file into another and modify it instead of writing a new one from scratch (beats me why they think this is efficient), forgetting to change the name of the include guard or only modifying the #ifdef part but not the #define part. Since a few years I teach them only to use #pragma once, and the problem has disappeared.
- pif 4y ago> 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.
- jhanschoo 4y agoIn the absence of an IDE to manage include guards, they are pointless busywork that make refactoring harder. The future solution would be C++ modules, but in absence of that pragma once is a lifesaver.
- hoten 4y agoOff topic, but TIL pragma once isn't part of the standard. I was wondering why clang-tidy didn't have a check for it...
- SAI_Peregrinus 4y agoC 11 standard, 6.10.6 "Pragma directive" A 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.
- jcelerier 4y ago> Unfortunately, there are very few developers working on the preprocessor and very few users of "#pragma once", so this will likely have very low priority unless one of those users takes the lead to fix it. $ cd $ rg --stats 'pragma once' -g '*.{h,hpp}?' 45406 matches frustrating