Date: Mon, 2 Jun 2025 11:44:20 +0200
There is also the possibilities of using type-information for this:
template</*arithmetic*/ T>
struct strictly_positive { T value; ...}
...
auto res = sqrt(strictly_positive{my_value});
But in all fairness, I think that the case of an optimization for a keyword
addition is 'weak'; we should let the compiler or possibly LTO 'erase'
branches that can be deduced unused in a function. Maybe having an
attribute to 'guide' the compiler optimization could be potentially useful
but:
1. it will only work when the definitions of a function is fully known
inside a translation unit (so practically inline-d or static)
2. it will probably invoke UB if it is violated
3. you would need to prove (show code for example) that you really can get
better performance at times when the compiler itself can't do the
optimization on its own.
// Robin
On Mon, Jun 2, 2025, 11:28 Peter Bindels via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I don't quite understand how the proposal is different from something like
> tag-invoke using templates, or regular function overloading. It'd convert
> the expression into a tag to use for invoking. Similarly, we can use
> template arguments to "assure" that something was checked before:
>
> float sqrt(float v assure(v>=0)) {
> if (v<0) throw std::runtime_error(...);
> ...
> }
>
> is basically the same as
>
> template <bool isKnownPositive>
> float sqrt(float v) {
> if (v<0) throw std::runtime_error(...);
> return sqrt<true>(v);
> }
>
> template <>
> float sqrt<true>(float v) {
> ...
> }
>
> which doesn't seem like much of an improvement? It has the same code bloat
> that templates has - arguably more, in case you have multiple assurements
> that not all are used - and it's a language addition that usually comes
> with a very high bar of "this is impossible to do right now without this".
>
> Why should we change the language for this instead of teaching the users
> about tag invoke?
>
> And in many cases it's changing a narrow contract (f only works on
> nonnegative numbers) into a wide contract (f works on anything but throws
> on negative), with an optimization to go back to the narrow contract. It's
> likely better to use the narrow contract in all cases instead.
>
> Best regards,
> Peter
>
> On Mon, Jun 2, 2025 at 9:13 AM SD SH <Z5515zwy_at_[hidden]> wrote:
>
>> Right.
>> Actually I realized [[assume]] is almost the same, so assure may be
>> superfluous.
>> ------------------------------
>> *发件人:* Peter Bindels <dascandy_at_[hidden]>
>> *发送时间:* 2025年6月2日 14:50
>> *收件人:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *抄送:* SD SH <Z5515zwy_at_[hidden]>
>> *主题:* Re: [std-proposals] 回复: 回复: 回复: A Proposal about A New Keyword
>> assure
>>
>> If I understand your proposal correcly, helped by clarifications asked by
>> many, it is the following:
>>
>> - A function marked with one or more `assure(x)` is compiled in multiple
>> different variants, one for each combination of assures.
>> - Calling such a function can be marked by one or more such `assure(x)`
>> expressions, which calls the variant that matches the assurances it gives.
>>
>> With the idea that if your caller guarantees it's not negative, you can
>> use the fast code path, and if they cannot it's the slow path. Similarly,
>> you could imagine a sqrt(complex) that has a faster implementation if it's
>> only a real argument, with a similar assure(c.im == 0) added.
>>
>> Basically, overloading on runtime argument guarantees.
>>
>> Is that correct?
>>
>> On Mon, Jun 2, 2025 at 7:14 AM SD SH via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>> Yeah, you're right. We should think of a way to find entry point, such as
>> processing assure before compiling codes so that compiler can generate
>> entry points.
>> If the function is not inlined? The optimization will be invaild.
>> Optimizing without inline is the main work of assure.
>>
>> ------------------------------
>> *发件人:* Std-Proposals <std-proposals-bounces_at_[hidden]> 代表 Simon
>> Schröder via Std-Proposals <std-proposals_at_[hidden]>
>> *发送时间:* 2025年6月2日 12:59
>> *收件人:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *抄送:* Simon Schröder <dr.simon.schroeder_at_[hidden]>
>> *主题:* Re: [std-proposals] 回复: 回复: A Proposal about A New Keyword assure
>>
>>
>> On Jun 2, 2025, at 6:55 AM, SD SH via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>> - Store entry points?
>>
>> No. Caller just finds the case it need.
>>
>>
>> How is the caller supposed to know if it does not see the function
>> definition? I would claim this is the common case. Mostly inline functions
>> are visible to the caller and the optimizer does already the right thing as
>> mentioned before.
>>
>> The function declaration would need a way to specify which assures are
>> valid.
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
template</*arithmetic*/ T>
struct strictly_positive { T value; ...}
...
auto res = sqrt(strictly_positive{my_value});
But in all fairness, I think that the case of an optimization for a keyword
addition is 'weak'; we should let the compiler or possibly LTO 'erase'
branches that can be deduced unused in a function. Maybe having an
attribute to 'guide' the compiler optimization could be potentially useful
but:
1. it will only work when the definitions of a function is fully known
inside a translation unit (so practically inline-d or static)
2. it will probably invoke UB if it is violated
3. you would need to prove (show code for example) that you really can get
better performance at times when the compiler itself can't do the
optimization on its own.
// Robin
On Mon, Jun 2, 2025, 11:28 Peter Bindels via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I don't quite understand how the proposal is different from something like
> tag-invoke using templates, or regular function overloading. It'd convert
> the expression into a tag to use for invoking. Similarly, we can use
> template arguments to "assure" that something was checked before:
>
> float sqrt(float v assure(v>=0)) {
> if (v<0) throw std::runtime_error(...);
> ...
> }
>
> is basically the same as
>
> template <bool isKnownPositive>
> float sqrt(float v) {
> if (v<0) throw std::runtime_error(...);
> return sqrt<true>(v);
> }
>
> template <>
> float sqrt<true>(float v) {
> ...
> }
>
> which doesn't seem like much of an improvement? It has the same code bloat
> that templates has - arguably more, in case you have multiple assurements
> that not all are used - and it's a language addition that usually comes
> with a very high bar of "this is impossible to do right now without this".
>
> Why should we change the language for this instead of teaching the users
> about tag invoke?
>
> And in many cases it's changing a narrow contract (f only works on
> nonnegative numbers) into a wide contract (f works on anything but throws
> on negative), with an optimization to go back to the narrow contract. It's
> likely better to use the narrow contract in all cases instead.
>
> Best regards,
> Peter
>
> On Mon, Jun 2, 2025 at 9:13 AM SD SH <Z5515zwy_at_[hidden]> wrote:
>
>> Right.
>> Actually I realized [[assume]] is almost the same, so assure may be
>> superfluous.
>> ------------------------------
>> *发件人:* Peter Bindels <dascandy_at_[hidden]>
>> *发送时间:* 2025年6月2日 14:50
>> *收件人:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *抄送:* SD SH <Z5515zwy_at_[hidden]>
>> *主题:* Re: [std-proposals] 回复: 回复: 回复: A Proposal about A New Keyword
>> assure
>>
>> If I understand your proposal correcly, helped by clarifications asked by
>> many, it is the following:
>>
>> - A function marked with one or more `assure(x)` is compiled in multiple
>> different variants, one for each combination of assures.
>> - Calling such a function can be marked by one or more such `assure(x)`
>> expressions, which calls the variant that matches the assurances it gives.
>>
>> With the idea that if your caller guarantees it's not negative, you can
>> use the fast code path, and if they cannot it's the slow path. Similarly,
>> you could imagine a sqrt(complex) that has a faster implementation if it's
>> only a real argument, with a similar assure(c.im == 0) added.
>>
>> Basically, overloading on runtime argument guarantees.
>>
>> Is that correct?
>>
>> On Mon, Jun 2, 2025 at 7:14 AM SD SH via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>> Yeah, you're right. We should think of a way to find entry point, such as
>> processing assure before compiling codes so that compiler can generate
>> entry points.
>> If the function is not inlined? The optimization will be invaild.
>> Optimizing without inline is the main work of assure.
>>
>> ------------------------------
>> *发件人:* Std-Proposals <std-proposals-bounces_at_[hidden]> 代表 Simon
>> Schröder via Std-Proposals <std-proposals_at_[hidden]>
>> *发送时间:* 2025年6月2日 12:59
>> *收件人:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
>> *抄送:* Simon Schröder <dr.simon.schroeder_at_[hidden]>
>> *主题:* Re: [std-proposals] 回复: 回复: A Proposal about A New Keyword assure
>>
>>
>> On Jun 2, 2025, at 6:55 AM, SD SH via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>> - Store entry points?
>>
>> No. Caller just finds the case it need.
>>
>>
>> How is the caller supposed to know if it does not see the function
>> definition? I would claim this is the common case. Mostly inline functions
>> are visible to the caller and the optimizer does already the right thing as
>> mentioned before.
>>
>> The function declaration would need a way to specify which assures are
>> valid.
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-06-02 09:44:40