with GCC 12, the following command fails with a fairly obscure error: $ gcc12.2.0 -c foo.h -o /dev/null foo.h:1: fatal error: cannot write PCH file: required memory segment unavailable compilation terminated. This also fails when invoked via g++. It works fine if the output is a normal file, and it always worked with previous GCC versions, so this is a pretty surprising change. This may seem like a strange thing to want to do, but I maintain a number of builds that do similar invocations to verify that each header file is self-contained. Either way, I think it would be best to fix it, or if that's not possible, it would be nice to improve the error message at the very least.
>it always worked with previous GCC versions Not really. Just by accident really. See r12-5320-ge4641191287ca6 Basically it means mmap failed on the file; well because mmap does not work on /dev/null .
>I maintain a number of builds that do similar invocations to verify that each header file is self-contained. You could just do: gcc -xc -include header.h /dev/null -o /dev/null -c Which works better and will always work when modules become standard ...
As long as I'm updating builds, I'll switch to that invocation, thanks. I still do think it's a little odd that in this case (and *only* in this case?) output needs to be written to a mappable file. That does not seem to be a typical implication of a -o flag of any tool I've ever used. And in fact your suggested change sort of proves my point... Why would a user suspect that /dev/null can be used for both input and output of that gcc -xc invocation, but not the other one?
(In reply to Matt Hellige from comment #3) > As long as I'm updating builds, I'll switch to that invocation, thanks. > > I still do think it's a little odd that in this case (and *only* in this > case?) output needs to be written to a mappable file. The way PCH works is mapping files in and out for speed reasons. So it is not really that odd. Even though it is not expliclty mentioned in the manual: https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Precompiled-Headers.html#Precompiled-Headers The whole idea of PCH is that the file is mapped in with almost no changes done afterwards so an exact dump of the memory from compiler can be loaded back in without doing anything special; rather the OS handles the loading into memory from the file.
That makes sense, but it's just a strange inconsistency from a usability point of view. .so files are generally mmapped as well, I believe, aren't they? But I can still generate one to /dev/null if I like: $ gcc12.2.0 -o /dev/null -rdynamic -shared foo.o bar.o -lrt ... Works fine.
(In reply to Matt Hellige from comment #5) > That makes sense, but it's just a strange inconsistency from a usability > point of view. > > .so files are generally mmapped as well, I believe, aren't they? But I can > still generate one to /dev/null if I like: > > $ gcc12.2.0 -o /dev/null -rdynamic -shared foo.o bar.o -lrt ... > > Works fine. Well so works differently because the linker produces runtime relocations for some segments of the shared objects which get applied at runtime. This is unlike pch which does have a relocation method but that method is slow. Also the linker is basically doing copies from other files into the final file while gcc is outputting its internals out for pch.
Those make sense as internal details. I don't think a typical user should be expected to guess or learn these differences in order to use the GCC from the command line. So, whether or not they suffice as justification for a command failing when it always worked with prior versions, I suppose will be a matter of taste.
I ran into the exact issue. Took me a while to figure out the issue was "-o /dev/null". The inconsistency also caught me off guard. I agree we need some consistency here.