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

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 26 09:38:10 PDT 2020


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

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200626/f8d0fd60/attachment.html>


More information about the cfe-dev mailing list