<div dir="ltr"><div dir="ltr">On Fri, 26 Jun 2020 at 09:38, Arthur O'Dwyer via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Fri, Jun 26, 2020 at 5:34 AM David Chisnall via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 26/06/2020 05:05, Louis Dionne via cfe-dev wrote:<br>
> Now, I understand this raises several questions. Of course, this couldn't be<br>
> done at the preprocessor level because I don't think we can know whether a<br>
> declaration exists at that time. However, I was curious to ask on this list<br>
> whether someone could think of a reasonable way to solve this problem.<br>
> <br>
> Having some mechanism for doing this would be a huge life improvement for libc++.<br>
<br>
I agree that something like this would be incredibly useful.  I wonder <br>
if it's sufficient to provide a built-in type trait and write something <br>
like:<br>
<br>
using FILE = std::conditional<__type_exists_v<::FILE>, ::FILE, void>;<br>
<br>
(With some built-in equivalent of std::conditional that does <br>
short-circuit evaluation)  You'd still have the std::FILE type, but it <br>
would be void on platforms where it didn't exist.</blockquote><div><br></div><div>I agree with Whisperity that having "FILE = void" on some platforms would be a cure worse than the disease.</div><div>It seems to me that what you want is less like an alias declaration and more like a using-declaration:</div><div><br></div><div>    namespace std {</div><div>        __using_if_exists ::FILE;</div><div>        __using_if_exists ::fopen;</div><div>     }</div><div><br></div><div>This syntax would also match Louis's original intent better, since the thing it's replacing is literally a using-declaration, not an alias declaration.</div><div>(I don't know off the top of my head whether there's a visible difference between `using ::T` and `using T = ::T`. I bet Richard knows. ;))</div></div></div></blockquote><div><br></div><div>I do, and there is, but I'm not sure if it'll be relevant here. "using T = ::T;" introduces a typedef-name, whereas "using ::T;" preserves the kind of the name. You can't refer to a name introduced by typedef-name with an elaborated-type-specifier (eg, "struct std::FILE" would be invalid with the "using T = ::T;" approach even if ::FILE is a struct), and you don't get the "non-types hide types" behavior with a typedef-name (which might have some impact on a hypothetical std::stat -- but that's not the only problem in that scenario).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>In any case, I concur with Louis that this seems like it'd have to be done at the C++ level, not the preprocessor level.</div><div><br></div><div>The semantics of my hypothetical "__using_if_exists QUALNAME;" declaration are that it does a name lookup on QUALNAME, and then if the lookup fails it does nothing, and if the lookup succeeds it acts like a regular `using` declaration. This feels like it should be super easy to implement as a compiler extension, right?</div><div>Bikeshed: __using_if_exists, __using_or_ignoring, __using_if_present, __using_unless_absent, __using_maybe_absent.</div><div><br></div><div>But, doesn't libc++ also need to work with GCC and maybe other compilers too? So won't you need to convince those compilers to implement whatever you pick here, or else keep the existing preprocessor hacks around forever anyway?</div><div><br></div><div>–Arthur</div></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></div>