C++ Logo

SG10

Advanced search

Subject: Re: [SG10] [isocpp-lib] [isocpp-core] Missing feature-test macros
From: Richard Smith (richardsmith_at_[hidden])
Date: 2019-10-04 15:33:13


On Fri, Oct 4, 2019 at 12:57 PM Barry Revzin <barry.revzin_at_[hidden]> wrote:

> On Fri, Oct 4, 2019, 1:51 PM Richard Smith <richardsmith_at_[hidden]>
> wrote:
>
>> On Fri, Oct 4, 2019 at 6:56 AM David Vandevoorde via Lib <
>> lib_at_[hidden]> wrote:
>>
>>> Thanks for that work, Barry!
>>>
>>
>> +1, this is great.
>>
>>
>>> I don’t disagree with any of your recommendations, and wholeheartedly
>>> agree with your constexpr changes.
>>>
>>> While going through it I found myself really not liking the name
>>> “__cpp_familiar_template_lambda”: I find it quite opaque. Is there is an
>>> opportunity to rename it to “__cpp_expl_lambda_template_parameters” or
>>> something like that?
>>>
>>
>> I'd prefer that we just bump the value of __cpp_generic_lambdas for this
>> rather than adding a new macro.
>>
>
> I'm okay with either of these.
>
>
>> __cpp_impl_constexpr_members_defined : not a huge fan of the name, but if
>> it's likely only going to be used in the stdlib implementation, maybe
>> that's fine.
>>
>> __cpp_lib_remove_cvref : does this need a macro? It seems like code
>> wishing to support old compilers could define it themselves or
>> unconditionally use remove_reference + remove_cv (I think this fails the
>> "you lose nothing by always behaving like the feature is not present" test,
>> unless I've overlooked a use case).
>>
>
> I wasn't sure about the traits. This one seems easily implantable (and the
> next two), so maybe not.
>
>
> I'm wondering the same thing for __cpp_lib_starts_ends_with. I'd imagine a
>> typical usage of that macro would be something like this (possibly factored
>> out into a helper function):
>>
>> #if __cpp_lib_starts_ends_with
>> if (s.starts_with("foo"))
>> #else
>> if (s.size() >= 3 && s.compare(0, 3, "foo"))
>> #endif
>>
>> I don't think that's worthwhile when you could instead write:
>>
>> // TODO(c++20): replace with s.starts_with("foo")
>> if (s.size() >= 3 && s.compare(0, 3, "foo"))
>>
>> Same thought for: __cpp_lib_type_identity, __cpp_lib_unwrap_ref (small
>> convenience functionality that you can write yourself with no loss of
>> functionality if you need it and can't depend on it being in the library).
>>
>
> starts_with/ends_with seems similar to consistent erasure to me, which
> does have a macro. It's implementable but obnoxious.
>

For me, some relevant questions are:
1) Is it possible to achieve the same thing (with the same compatibility
story) with and without the feature test macro? (If not, then that's a good
argument for the macro.)
2) Is the version using the feature test macro better in some way? (If not,
then that's a good argument against the macro.)

I think for small library functionality like this, the answers are yes and
no, respectively. From my perspective, the version using the macro is
worse, because it's functionally identical but is more complex and has a
larger configuration matrix (so needs additional work to properly test
across compiler versions).

For larger pieces of standard library functionality, where some third-party
library might disable parts of itself if the standard library support is
unavailable, I think a feature test macro is warranted. (Example: for
atomic float and atomic shared_ptr and for syncbuf, a third-party library
could only support single-threaded usage if standard library support is
unavailable.) Similarly for things that need compiler support, but can be
worked around (eg, for assume_aligned you can just not call it if it
doesn't exist), or for things where it's easier to disable third-party
library functionality rather than reimplementing (eg, you could use
is_nothrow_convertible when available, and make part of your library
unconditionally noexcept(false) otherwise).

> __cpp_lib_constexpr_complex, __cpp_lib_constexpr_array_comparisons, __cpp_lib_constexpr_pointer_traits
>> : I seem to recall a discussion in L(E?)WG about moving away from
>> fine-grained constexpr feature test macros for the stdlib towards
>> periodically bumping __cpp_lib_constexpr. How do these fit into that?
>>
>
> Do you have a link? The only paper I currently have associated with
> __cpp_lib_constexpr on SD-6 is P1032R1.
>

http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2019/p1424r1.html

> Regarding the new set of constexpr macros (__cpp_constexpr_virtual,
>> try_catch, ...): do those benefit any implementation? (Clang at least has
>> already released some of these features without the additional macros, so
>> they're no help there for the previous release, and now implements the full
>> set of these, so the fine-grained macros are no help for the next release
>> either.) I think we need to be careful about adding too many macros -- each
>> feature test macro we add introduces a small amount of overhead to every
>> compilation, and that adds up. (Incidentally this is why the original
>> proposal was for a single __has_feature(x) mechanism: that avoids the need
>> to pre-populate all the feature test macros in the macro table. But that
>> ship has sailed.) I think it's preferable for users to just have a value
>> that means "you get to use the C++20 constexpr rules" if no-one is going to
>> ship a compiler that has only part of the rules (apart from dynamic
>> allocation, which has its own macro).
>>
>
> Maybe we could just remove the restriction that constexpr functions have
> to be constant expressions for at least one set of arguments (otherwise
> ILNDR). That way, we could just mark things constexpr even if some
> compiler/library doesn't provide it yet?
>
> My motivation with these finer grained macros was to let you do
> conditional constexpr where possible. If implementations just batch these
> anyway, then maybe the fine grain wouldn't provide any value, and you just
> check for the one value you want?
>

Yeah. I think this depends a lot on what implementers actually do, though.
(This is a major downside of moving the feature test macros to the standard
draft: they can't nimbly reflect actual implementation practice any more,
and we're left guessing what different vendors will ship in the same
compiler version.)

> For __cpp_nodiscard_reason: I'm opposed to adding this macro in isolation.
>> Either we need to accept that version numbers for feature test macros don't
>> work (the magic numbers are too magical) and completely rethink our
>> approach, or we do not have adequate rationale for this.
>>
>
> Understood.
>
> Barry
>
>>



SG10 list run by sg10-owner@lists.isocpp.org