[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