[Development] Using #pragma once

Henry Skoglund fromqt at tungware.se
Mon Oct 8 08:23:39 CEST 2018


On 2018-10-08 07:13, Thiago Macieira wrote:
> On Sunday, 7 October 2018 15:17:30 PDT Henry Skoglund wrote:
>>> I recommend against changing Qt.
>>
>> Hi, but isn't C++17's __has_include preprocessor cmd an implicit
>> endorsement of #pragma once? I mean, they both assume that the file
>> namespace is stable and idempotent.
> 
> No, I don't see how one thing has to do with the other.
> 
> __has_include imples that the #include will not fail with "No such file or
> directory" and hopefully won't fail either with "Is a directory". Other checks
> are welcome, but I wouldn't be too picky if they didn't get done.
> 
> #pragma once only applies after the #include and changes nothing about whether
> the #include succeeds or not.
> 
>> The example with ~/src as a bind-mount to ~/dev/src above, reminds me of
>> the old pointer aliasing problems in C++. But cannot it be solved by
>> requiring #pragma once to always call realpath() first, i.e. always test
>> on "the canonicalized absolute pathname" that realpath() returns?
> 
> No.
> 
> $ realpath ~/dev/src/qt/ ~/src/qt
> /home/tjmaciei/dev/src/qt
> /home/tjmaciei/src/qt
> 
> Bind-mounts are not symlinks. For all intents and purposes they are different
> filesystems: you can't link() from one to the other, for example. You may be
> able to tell that they are the same because the dev_t is the same:
> 
> $ stat -c '%D %i %n' ~/dev/src ~/src
> fe03 4456449 /home/tjmaciei/dev/src
> fe03 4456449 /home/tjmaciei/src
> 
> But to tell that the file is the same you'd need to compare inodes and those
> are not guaranteed on network mounts.
> 
> Another option is to use name_to_handle_at(), a Linux-specific function, but
> that will also fail with bind mounts and multiple mounts of the same
> filesystem. The manpage suggests resolving mount IDs to actual disks by
> looking for them in /dev/disks/by-uuid.
> 
> So you see why this is not a very easy solution.
> 

Yes, I see.

When #pragma once was introduced 20 years ago by Microsoft I thought it 
was the greatest thing since sliced bread, but maybe it's time to 
reconsider.

So, what about a new preprocessor command:

__has_same_md6_digest

It would require the compiler to store an md6 hash/checksum of the 
contents of each of the #include files seen during compilation, but if 
most of the compiler's time is spent waiting for file i/o, then 
computing those md6 sums wouldn't be so costly.

It would work the same way as the traditional header guards, but more 
automated, example:

#if !__has_same_md6_digest
...
...
...
#endif

Rgrds Henry




More information about the Development mailing list