<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 26, 2020, at 12:38, Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com" class="">arthur.j.odwyer@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div dir="ltr" class="">On Fri, Jun 26, 2020 at 5:34 AM David Chisnall via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class=""></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;">On 26/06/2020 05:05, Louis Dionne via cfe-dev wrote:<br class="">> Now, I understand this raises several questions. Of course, this couldn't be<br class="">> done at the preprocessor level because I don't think we can know whether a<br class="">> declaration exists at that time. However, I was curious to ask on this list<br class="">> whether someone could think of a reasonable way to solve this problem.<br class="">><span class="Apple-converted-space"> </span><br class="">> Having some mechanism for doing this would be a huge life improvement for libc++.<br class=""><br class="">I agree that something like this would be incredibly useful.  I wonder<span class="Apple-converted-space"> </span><br class="">if it's sufficient to provide a built-in type trait and write something<span class="Apple-converted-space"> </span><br class="">like:<br class=""><br class="">using FILE = std::conditional<__type_exists_v<::FILE>, ::FILE, void>;<br class=""><br class="">(With some built-in equivalent of std::conditional that does<span class="Apple-converted-space"> </span><br class="">short-circuit evaluation)  You'd still have the std::FILE type, but it<span class="Apple-converted-space"> </span><br class="">would be void on platforms where it didn't exist.</blockquote><div class=""><br class=""></div><div class="">I agree with Whisperity that having "FILE = void" on some platforms would be a cure worse than the disease.</div><div class="">It seems to me that what you want is less like an alias declaration and more like a using-declaration:</div></div></div></div></blockquote><div><br class=""></div><div>Indeed, I don't think FILE = void is a viable path forward. Also, it wouldn't work for things that aren't types, which is actually the vast majority of such using declarations (memcpy & friends, etc).</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_quote"><div class=""><br class=""></div><div class="">    namespace std {</div><div class="">        __using_if_exists ::FILE;</div><div class="">        __using_if_exists ::fopen;</div><div class="">     }</div><div class=""><br class=""></div><div class="">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 class="">(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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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></div></div></blockquote><div><br class=""></div><div>Yes, that's exactly what I was asking. I wondered whether folks could spot a fundamental issue with doing this, but it looks like perhaps there is none.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_quote"><div class="">Bikeshed: __using_if_exists, __using_or_ignoring, __using_if_present, __using_unless_absent, __using_maybe_absent.</div><div class=""><br class=""></div><div class="">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></div></div></blockquote><div><br class=""></div><div>AFAICT, libc++ works with recent-ish GCCs and Clang, that's it. There's been some work for it to work on other compilers, but none of it is maintained, and all of it is probably broken -- as far as I'm aware.</div><div><br class=""></div><div>If we went down that route, I'd kindly ask GCC to implement the same builtin, and if they say no, I could always resort to:</div><div><br class=""></div><div>#if defined(__GNUC__)</div><div>#  define _LIBCPP_USING_IF_EXISTS(...) using __VA_ARGS__</div><div>#else</div><div>#  define _LIBCPP_USING_IF_EXISTS(...) __using_if_exists __VA_ARGS__</div><div>#endif</div><div><br class=""></div><div>Or whatever form that ends up taking. I might have to keep existing workarounds for a little bit, but it would be reasonable to require that this extension be supported in order to add support for a new platform. Otherwise the headers just become a huge spaghetti.</div><div><br class=""></div><div>Louis</div><div><br class=""></div></div></body></html>