As usual, the devil lies in the detail. If you want to make pragma once robust you need to checksum files, which in the end will be slower than include guards.
#pragma once can be defined in terms of a reference model whereby it is equivalent to a machine-generated sequence:
#ifndef <ident>
#define <ident>
#endif
where the detailed semantics is tied to how the machine generates <ident>.If <ident> is a digest of the absolute path, then references to the same file via different hard or symbolic links look different and do not mutually exclude.
If <ident> is produced from the volume and object identifier (like inode number) then different links to the same header will mutually exclude.
If <ident> is a content hash, then identical files will mutually exclude (but we need to deal with hash collisions somehow).
A much better solution would be to sidestep this whole thing entirely and just allow any file-scope definition in C++ to be repeated in the same translation unit (with some proviso, like that the multiple definitions have to be identical; and that could be enforced with diagnostics). The multiple inclusions of the same material aren't a problem.
You could say that. I didn't. Bolting on some sort of module system is just a totally different scope of enhancement than my modest proposal.
> As usual, the devil lies in the detail. If you want to make pragma once robust you need to checksum files, which in the end will be slower than include guards.
That's just not true. It doesn't need to be robust against byzantine source trees and/or build systems to be defined in the C standard or to be useful. The standard can leave the concept of "the same file" implementation-defined, as it does many other concepts.
On Unix system C implementations, it is sufficient to use stat() and compare st_ino and st_dev against previously observed values for a given compilation unit. You do not need to checksum files. You especially do not need to write the specific behavior of checksumming header files into the C standard.
A locally developed hack, or even a compiler extension, doesn't have to be; an ISO-standard feature should be well specified.
If something is specified in such a way that it is less robust than the #ifndef trick, then any programmer worth their salt will use the #ifndef trick.
An acceptable pragma-once would look like this:
#pragma once 9DF9-C3D9-BDF0
Basically it should take an argument string which specifies an ID for the file, intended to be unique.That claim doesn't match up with the C standard I've read. I.e., this is an "isolated demand for rigor." Are we looking at the same document? Quite a lot is underspecified or implementation defined to accommodate differences in architectures and systems.
The 2018 C standard doesn't specify whether NULL is a pointer or integer; what a null pointer's representation is; nor the representation of negative (signed) integers. The C standard defines some loose requirements around observable behavior and leaves the specific details to the implementation.
> Basically it should take an argument string which specifies an ID for the file, intended to be unique.
Or the standard could leave it up to the implementation to identify file uniqueness without this additional, incompatible argument. Like I said before, all you have to do for Unix implementations to be as robust as the stupid ifndef trick is to check st_ino and st_dev.
It's important to recognize that implementations and implementation details are distinct from the standard.
Also note that the ifndef hack is non-robust in its own way — false positive exclusions due to accidental identifier conflicts. #pragma once does not have this problem.