As you might have heard, in the newest version of GCC, <cassert> is no longer included by <bits/stdc++.h> (you can view the change here). This means that the following code will now fail to compile:
#include <bits/stdc++.h>
int main() {
assert(1);
}
I noticed this issue during a recent compiler update on QOJ, where it broke a large number of older submissions. Because of this, I have reverted the compiler back to GCC 15.2.0 for now.
Of course, this is not the first time that a compiler or language-standard update has broken older code. However, I found this change seems to affect much more existing submissions than previous ones. Although GCC 16 was only released a few months ago and probably will not affect most contests immediately, platforms will eventually upgrade to newer GCC versions. I wanted to bring this issue to your attention and, in particular, hear your comments and suggestions.








Since
bits/stdc++.his not a standard header, could the include directory of the compiler used by the online judge be modified, like AtCoder did when adding AC-Library, so thatcassertis included again in that header?What a BS, whose life will be improved by this change?
Primary purpose of
bits/stdc++.his that of a precompiled header, or a header unit, that is of things that you compile once, and any repeated compilation would use the cache instead of doing everything again.Using it properly makes compilation time of CP-grade programs near-instant, but in the case of
cassertspecifically, the issue is that whetherassertactually does anything is controlled byNDEBUGcompilation flag, as it should only work in debug builds, and not in release.Because it's a compilation-time control, as the commit message suggests,
cassertis not suitable to be a part ofbits/stdc++.hwhen it is used properly as a precompiled header or a header unit.I don't understand around 90% of words that you used in your comment, so I won't comment on the main issue, but I'll inquire about "Using it properly makes compilation time of CP-grade programs near-instant". What makes for a proper usage of it? What is "near-instant" in seconds? Whenever I compile my cp codes it always takes a few seconds, which I'd hardly call "near-instant", but maybe it can be called like that given that this header theoretically includes a ton of things?
The reason why you aren't noticing a difference is likely because you aren't using a precompiled version of the header file (which would end with
.gchif compiling with gcc). Precompiled headers take out a good chunk of the work (especially for something as large asbits/stdc++.hwhich usually takes >1s) because, as the name implies, they have already been compiled; you don't need to recompile them each time. Some useful resources are below.bits/stdc++.hadds non-negligible time to compilationSee his link about precompiled headers. You don't use precompiled headers when you compile your cp codes, you just include headers as normal. In order to use one, you'd have to precompile it on your system first.
I tested it out of curiosity and a blank main with
#include "bits/stdc++.h"goes from 2 seconds to 0.6s on my system when I precompile it. For complex programs it's going to vary.Proper usage is to actually precompile it as a
.gchfile or a module, and tell compiler to use it.I think this GCC page provides a nice usage example with modules:
You do this (add your custom compilation flags to both commands), and then it's realistic to reduce compilation time from ~2s to 0.2s-0.5s. You may need to use
-fmodules-tsinstead of-fmodules, or use precompiled header approach (see below), depending on your GCC version.Legacy way to do it is to locate
stdc++.hfile in your system, and applyg++to it directly (without module flags, just same command as for your main file), and it will producestdc++.h.gchfile. You can leave it in system include path, or drop it in your code folder, and it should produce the same effect (and is sometimes more stable). You may need to add-include stdc++.hto your command.If in doubt, you can use
-H, aka--trace-includes, to verify whether the compiler actually used it as a precompiled header, or it still includes all individual headers one by one.Oh no.It means that I should write a another
#includewhen I want to useassert.