[cfe-dev] RFC: A mechanism for importing a declaration only when it exists

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 26 14:08:03 PDT 2020

On Fri, 26 Jun 2020 at 09:38, Arthur O'Dwyer via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Fri, Jun 26, 2020 at 5:34 AM David Chisnall via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>> On 26/06/2020 05:05, Louis Dionne via cfe-dev wrote:
>> > Now, I understand this raises several questions. Of course, this
>> couldn't be
>> > done at the preprocessor level because I don't think we can know
>> whether a
>> > declaration exists at that time. However, I was curious to ask on this
>> list
>> > whether someone could think of a reasonable way to solve this problem.
>> >
>> > Having some mechanism for doing this would be a huge life improvement
>> for libc++.
>> I agree that something like this would be incredibly useful.  I wonder
>> if it's sufficient to provide a built-in type trait and write something
>> like:
>> using FILE = std::conditional<__type_exists_v<::FILE>, ::FILE, void>;
>> (With some built-in equivalent of std::conditional that does
>> short-circuit evaluation)  You'd still have the std::FILE type, but it
>> would be void on platforms where it didn't exist.
> I agree with Whisperity that having "FILE = void" on some platforms would
> be a cure worse than the disease.
> It seems to me that what you want is less like an alias declaration and
> more like a using-declaration:
>     namespace std {
>         __using_if_exists ::FILE;
>         __using_if_exists ::fopen;
>      }
> 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.
> (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. ;))

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).

> 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.
> 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?
> Bikeshed: __using_if_exists, __using_or_ignoring, __using_if_present,
> __using_unless_absent, __using_maybe_absent.
> 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?
> –Arthur
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200626/0841ca7c/attachment.html>

More information about the cfe-dev mailing list