Title
Time utility arithmetic constexpr functions have invalid effects
Status
c++11
Section
[time.duration.nonmember]
Submitter
Daniel Krügler

Created on 2010-12-06.00:00:00 last changed 161 months ago

Messages

Date: 2011-03-14.23:04:34

Proposed resolution:

The suggested wording changes are against the working draft N3242. Additional to the normative wording changes some editorial fixes are suggested.

  1. In [time.duration.nonmember], change the following arithmetic function specifications as follows:

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>{>}::type
    operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
    

    2 Returns: CD(lhs) += rhsCD(CD(lhs).count() + CD(rhs).count()).

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>{>}::type
    operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
    

    3 Returns: CD(lhs) -= rhsCD(CD(lhs).count() - CD(rhs).count()).

    template <class Rep1, class Period, class Rep2>
    constexpr duration<typename common_type<Rep1, Rep2>::type, Period>
    operator*(const duration<Rep1, Period>& d, const Rep2& s);
    

    4 Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2).

    5 Returns: duration<CR(Rep1, Rep2), Period>(d) *= sCD(CD(d).count() * s).

    [...]

    template <class Rep1, class Period, class Rep2>
    constexpr duration<typename common_type<Rep1, Rep2>::type, Period>
    operator/(const duration<Rep1, Period>& d, const Rep2& s);
    

    8 Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not an instantiation of duration.

    9 Returns: duration<CR(Rep1, Rep2), Period>(d) /= sCD(CD(d).count() / s).

    [...]

    template <class Rep1, class Period, class Rep2>
    constexpr duration<typename common_type<Rep1, Rep2>::type, Period>
    operator%(const duration<Rep1, Period>& d, const Rep2& s);
    

    11 Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not an instantiation of duration.

    12 Returns: duration<CR(Rep1, Rep2), Period>(d) %= sCD(CD(d).count() % s)

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
    operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
    

    13 Returns: common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type(lhs) %= rhsCD(CD(lhs).count() % CD(rhs).count()).

Date: 2011-02-17.00:00:00

[ 2011-02-17 Reflector discussion ]

Moved to Tentatively Ready after 5 votes.

Date: 2010-12-06.00:00:00

As of issue 1171 several time-utility functions have been marked constexpr. Alas this was done without adapting the corresponding return elements, which has the effect that none of current arithmetic functions of class template duration marked as constexpr can ever be constexpr functions (which makes them ill-formed, no diagnostics required as of recent core rules), because they invoke a non-constant expression, e.g. [time.duration.nonmember]/2:

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>{>}::type
operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

2 Returns: CD(lhs) += rhs.

The real problem is, that we cannot defer to as-if rules here: The returns element specifies an indirect calling contract of a potentially user-defined function. This cannot be the += assignment operator of such a user-defined type, but must be the corresponding immutable binary operator+ (unless we require that += shall be an immutable function which does not really makes sense).

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2011-04-11 11:23:23adminsetstatus: voting -> wp
2011-03-05 15:24:28adminsetstatus: ready -> voting
2011-02-17 18:20:14adminsetmessages: + msg5500
2011-02-17 18:20:14adminsetstatus: new -> ready
2010-12-06 22:01:41adminsetmessages: + msg5461
2010-12-06 00:00:00admincreate