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

Marcus Johnson via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 26 11:19:02 PDT 2020


That seems like a great approach.

One question tho, can we make this publically available?

In my case, char16_t and char32_t are not builtin types, they're defined in uchar.h, and the workarounds I'm currently using are pretty hackish, so it'd be great if there was a `__type_exists(char16_t)` operator or maybe `__type_matches(char16_t, uint_least16_t)`, preferably that was part of the preprocessor.

> On Jun 26, 2020, at 12:05 AM, Louis Dionne via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> 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
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list