On Wed, Mar 3, 2021 at 11:46 AM Tom Tromey <tom@xxxxxxxxxx> wrote: > > It's also worth noting that in GCC it is slower than include guards. > See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58770 > > It's just a bug, probably easy to fix. On the other hand, nobody has > ever bothered to do so. That bugzilla is actually worth reading, if only to explain how the include guard is more robust technology compared to #pragma once. The traditional include guarding with #ifndef/#define/#endif around the contents has the advantage that a compiler _can_ generate the obvious trivial optimizations of just memoizing that "oh, I've seen this filename already, and it had that include guard pattern, so I don't need to include it again". But, I hear you say "that's exactly what '#pragma once' does too!". No, it's not. There's actually two huge and very fundamental differences between '#pragma once' and the traditional include guard optimization: (a) the traditional include guard optimization HAS NO HIDDEN SEMANTIC MEANING. It's a pure optimization that doesn't actually change anything else. If you don't do the optimization, absolutely nothing changes. (b) the traditional include guard model allows for overriding and is simply more flexible And the GCC bugzilla talks about some of the issues with (a), and I already mentioned one similar issue with (a) wrt sparse: exactly what is it that "#pragma once" really protects? Is it the filename? Is it the _canonical_ filename? What about symbolic links or hardlinks? Is it the inode number? What about filesystems that don't really have those concepts? The above questions aren't some made-up example. They are literally FUNDAMENTAL DESIGN MISTAKES in "#pragma once". In contrast, include guards just work. You give the guard an explicit name, and that solves all the problems above, and allows for extra flexibility (ie the (b) issue: you can override things and include things twice if you know you're playing games, but you can also use the guard name to see "have I already included this file" for when you have possible nasty circular include file issues etc). So the traditional include guard model is simply technically the superior model. This is why I'm NAK'ing "#pragma once". It was never a good idea, and the alleged advantage ("faster builds by avoiding double includes") was always pure garbage because preprocessors could do the same optimization using the traditional include guards. In fact, because the traditional include guards have well-defined meaning and doesn't have any of the questions about what makes a file unique, and a missed optimization doesn't cause any semantic differences, a compiler has a much _easier_ time with that optimization than with the ostensibly simpler "#pragma once". Most #pragma things are not wonderful. But '#pragma once' is actively bad. Linus