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

Louis Dionne via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 25 21:05:17 PDT 2020


Hi,

The C++ Standard Library has multiple headers of the form <cfoobar>, which are
basically importing declarations from the corresponding <foobar.h> header into
namespace std. For example, <cstdio> basically imports all the declarations from
<stdio.h> into namespace std:

    namespace std {
        using ::FILE;
        using ::fpos_t;
        using ::size_t;
        ...
    }

When porting libc++ to new platforms, especially more embedded-ish platforms, 
it is very common that some declarations are not provided by the underlying
C Standard Library. This leads to having to detect what platform we're on,
and then to conditionally exclude some declarations:

    namespace std {
    #if !defined(SOME_WEIRD_PLATFORM)
        using ::FILE;
        using ::fpos_t;
    #endif
        using ::size_t;
    }

Unfortunately, different platforms often offer slightly different subsets, so
these #ifs quickly become difficult to maintain. Trying to find common themes
for excluding declarations (e.g. #if !defined(_LIBCPP_HAS_NO_FILE)) is vain,
because the subset provided by a platform is often arbitrary. For example, I've
seen platforms where malloc() and free() were not provided, however operator new
was -- so trying to carve out something like _LIBCPP_HAS_NO_ALLOCATION wouldn't
really make sense.

Given the difficulty of manually excluding such using declarations, I came to
the conclusion that what we wanted was often something like (pseudocode):

    namespace std {
    #if __has_declaration(::FILE)
        using ::FILE;
    #endif

    #if __has_declaration(::fpos_t)
        using ::fpos_t;
    #endif

    #if __has_declaration(::size_t)
        using ::size_t;
    #endif

        ...
    }

Basically, we want to import each declaration into namespace std only if the
global namespace has such a declaration.

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

Cheers,
Louis



More information about the cfe-dev mailing list