<div dir="ltr">This is long-standing intended behavior and I doubt it could reasonably be changed now. The scenario where you actually <i>want</i> to include the same #pragma once file-content twice, under two different filenames, is nearly nonexistent IME.<div><br></div><div>I think the critical problem this behavior solves is that directory softlinks in the include paths can easily result in multiple paths pointing to the same file. These must be resolved as equivalent, or you'll get spurious multiple-include errors, in real-world scenarios. It may also have been workable to just resolve all symlinks in the path to get a canonical path first, and compare those canonical paths to determine file-equivalence, instead of using device/inode of the kernel-resolved file. But I doubt if it's reasonable to change that now -- I expect it will break things for some people, and there doesn't seem to be enough of a corresponding upside to compensate for that breakage.</div><div><br></div><div>That said, I have seen problems arise from CAS header differences -- but from a different area: #include_next. If you have two headers named "foo.h" in different directories that say:</div><div><span style="font-family:monospace">#include_next "foo.h"</span><br></div><div>they have the same content, but they are not at all equivalent-behaving. In order to determine what "next" means, clang needs to know which include-path the header was found from. And I forget the exact details of what goes wrong, but IIRC, clang doesn't do this in the straightforward obvious way of simply remembering where in the search it found the current header. Instead, it reconstructs it from data cached off to the side, which gets confused by content-addressed storage, because each header can only be cached as being in a single parent directory, or something like that. Anyhow, the one time this problem came up, I didn't end up figuring out how to do a proper fix, and just worked around the problem by adding a comment to one of the instances of the files, making it no longer have the same hash as the other file.</div><div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 28, 2021 at 1:44 PM Shoaib Meenai via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">





<div lang="EN-US" style="overflow-wrap: break-word;">
<div class="gmail-m_-2153985133527953052WordSection1">
<p class="MsoNormal"><span style="font-size:11pt">We have a remote build system that uses content-addressed storage, in which all files with the same content are hard linked. I noticed that our output object files differed when they were compiled locally
 vs. remotely, and it turns out that #pragma once considers hard links to be identical, regardless of their path. Our local builds don’t have the hard linking but our remote builds do, so the include tree is different between local and remote builds (because
 of the #pragma once behavior difference), which causes debug info to differ.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">Is this behavior desirable? You can construct a convoluted example that works when you copy a file and fails when you hard link it:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ cat evil.h<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#pragma once<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#ifdef EVIL_ONE<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#define EVIL_TWO<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#endif<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#define EVIL_ONE<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ cp evil.h evil2.h<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ cat evil.c<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#include "evil.h"<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#include "evil2.h"<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#ifndef EVIL_TWO<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#error Not evil enough<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#endif<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ clang -c evil.c<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""># compiles successfully<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ rm evil2.h<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ ln evil.h evil2.h<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">$ clang -c evil.c<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">evil.c:4:2: error: Not evil enough<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">#error Not evil enough<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">^<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">1 error generated.</span><span style="font-size:11pt"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">gcc behaves the same as clang in this case, for what it’s worth.
<a href="https://bugs.llvm.org/show_bug.cgi?id=26579" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=26579</a> looks related, although my question is specifically about #pragma once’s intended behavior.<u></u><u></u></span></p>
</div>
</div>

_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>