RFR (tedious) 8216022: Use #pragma once

Kim Barrett kim.barrett at oracle.com
Sun Jan 6 18:44:05 UTC 2019


> On Jan 5, 2019, at 10:03 AM, Erik Österlund <erik.osterlund at oracle.com> wrote:
> 
> Hi Andrew,
> 
> On 2019-01-05 12:31, Andrew Haley wrote:
>> On 1/4/19 3:59 PM, Erik Österlund wrote:
>>> On 2019-01-04 15:59, David Lloyd wrote:
>>>> In addition, it was pointed out to me that if, for some reason, a
>>>> header file ends up in more than one location on the include path,
>>>> #pragma once will (probably, as it's not standardized) allow it to
>>>> be included twice, which #ifdef guards avoid.  This is perhaps not
>>>> a real concern in this particular code base though.
>>> 
>>> That sounds like a bug. Just because something is implementation
>>> defined, doesn't make it okay or expected to not work. Do you know
>>> how to reproduce this, and on which platform/compiler/version?
>>> Obviously, if this was an issue in our code base, one would quickly
>>> notice it doesn't build.
>> It's not a bug, exactly. It's that the question of "is this the same
>> file?" is extremely difficult to answer definitively. Not all
>> filesystems give you a reliable way to answer that question. Sure, you
>> can kludge around the problem with modification times and maybe even a
>> collision-free hash, but getting it really correct is not going to be
>> efficient, and not even possible until that question is rigorously
>> defined. There's a good reason why #pragma once still isn't standard.
> 
> Perhaps. Yet Java has to support Path.toRealPath(), which resolves symlinks. And similarly, realpath() has been part of the POSIX standard since 2008. And even C++17 defines std::filesystem::canonical() as part of the standard. So it seems to me that any system that can't build HotSpot because of the inadequacy of the underlying system to tell symlinked files apart, will also not be able to support said standardized APIs either. Unless again someone shoots himself/herself in the foot intentionally and actually keeps 2 copies of the same file around, and includes both. We should *never* do that, and I would love to get a compiler error if anyone tried to do that.
> 
> I have asked this before, but does anyone actually know of a compiler/os/filesystem combo that has a #pragma once implementation that gets confused about symbolic links or different include paths, or is this all a hypothetical problem, for a hypothetical compiler+os+filesystem combo that can probably never support e.g. C++17? Perhaps a simple test could be written for this that fails reliably on such systems, so we don't get any surprises. I would rather test this to see if it is a problem or not, instead of having a long hypothetical argument about it, based on what somebody told somebody, with guesses about how relevant compilers may or may not handle this differently and may or may not have different interpretations about whether files should be canonicalized or not.

Symlinks might have been a problem in the past; I don't think they
have been for a long time. I never mentioned them in my initial
analysis.

The cases where it's hard (perhaps impossible?) to determine that two
files are the same that I've heard of involve different mount points
that can get you to the same place. For example, there were these
references from my earlier message:

---------- 
Some examples are discussed in the following messages.  Having a
bind-mount involved can mess things up, for example.  I don't know if
that's a realistic scenario for building the JDK or HotSpot.
https://lists.qt-project.org/pipermail/development/2018-October/067467.html
https://lists.qt-project.org/pipermail/development/2018-October/067471.html
----------

The second of those describes cases where realpath doesn't transform
two different paths to the same location to the same canonical path.
It's not even clear what a "canonical" path would be for some cases
like this. This is the sort of thing that I assume has given the
committee pause when considering standardization of such a feature.

Whether such a setup is at all plausible when building HotSpot is a
rather different question. I suspect the answer is no, or at least one
would have to work hard to produce a problem. But I long ago stopped
assuming that users wouldn't do things that seemed strange to me.

The way that include paths can get one in trouble has to do with the
"usual" behavior of '#include "..."' starting the search with respect
to the current directory. (I've seen discussions in some projects
suggesting that one should always use <...> syntax for include, to
never bypass the configured include path.) I think the problematic
cases related to this cannot happen for HotSpot, so long as there
aren't "junk" files with inopportune names in the source tree. But
there are ways for such to cause problems regardless, so I don't
consider that a problem for this discussion.

I don't presently have a strong opinion on the matter. But I do want
it to be considered on its real merits, and not seemingly obsolete
issues like problems with symlinks.



More information about the hotspot-dev mailing list