Discussion:
[std-proposals] Always defer evaluation of static_assert to template instantiation time.
Bengt Gustafsson
2018-10-19 01:16:57 UTC
Permalink
It seems a recurring pattern that you try to use static_assert(false); in
template code to indicate that a template should not be instantiated, but
this currently does not work as the assert fires before the template is
ever instantiated. A work around I have seen is:

// Delay evaluation of the assert by making it dependent on a template parameter

This line has a comment.Add a comment on this line.

33
+

static_assert(sizeof(ExprT) == -1, "Conversion between these types is not supported");


It seems to me that it would be a reasonable change to not let a static_assert(false) fire in template code unless the template is actually instantiated.


Are there any show-stoppers preventing such a change?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org.
Nicolas Lesser
2018-10-19 14:20:51 UTC
Permalink
The problem with this is that it would special case the condition of
staric_assert.

If the condition in a template is not value-dependent, and it evaluates to
false, then the program is ill-formed. [temp.res]p8


IMO the right solution would be to not use such a static_assert. You can
always delete an overload, make an incomplete type, ... if you don't want
people using that particular instantiation.

On Fri, Oct 19, 2018, 3:16 AM Bengt Gustafsson <
Post by Bengt Gustafsson
It seems a recurring pattern that you try to use static_assert(false); in
template code to indicate that a template should not be instantiated, but
this currently does not work as the assert fires before the template is
// Delay evaluation of the assert by making it dependent on a template parameter
This line has a comment.Add a comment on this line.
33
+
static_assert(sizeof(ExprT) == -1, "Conversion between these types is not supported");
It seems to me that it would be a reasonable change to not let a static_assert(false) fire in template code unless the template is actually instantiated.
Are there any show-stoppers preventing such a change?
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq3MY4dkqhgiSCQRqJh0GCu-APM-M458sk7HzYJdWwgZqw%40mail.gmail.com.
Bengt Gustafsson
2018-10-19 15:32:10 UTC
Permalink
Well, you pointing at the rule I want to change as a motivation for not
changing the rule does not lead very far. If I wasn't proposing a change to
the language I would not be posting on this list.

There is already special handling of the boolean expression in a
static_assert compared to other constexpr boolean expressions: It causes a
compilation error if false. It can't be a big deal for a compiler to defer
the constexpr execution of this particular boolean expression to template
instantiation time if encountered in template code.

The example I gave (not by my hand) is typical of the trickery people
employ to avoid this problem, which is ugly and hard to understand.

The ideas you propose as alternatives have the drawback that they don't
allow you to affix your own error message (which was the reason to add
static_assert in the first place). Also there is no technique that works in
all contexts where static_asserts work, so you'd have to think of how to
get the effect each time.
Post by Nicolas Lesser
The problem with this is that it would special case the condition of
staric_assert.
If the condition in a template is not value-dependent, and it evaluates to
false, then the program is ill-formed. [temp.res]p8
IMO the right solution would be to not use such a static_assert. You can
always delete an overload, make an incomplete type, ... if you don't want
people using that particular instantiation.
Post by Bengt Gustafsson
It seems a recurring pattern that you try to use static_assert(false); in
template code to indicate that a template should not be instantiated, but
this currently does not work as the assert fires before the template is
// Delay evaluation of the assert by making it dependent on a template parameter
This line has a comment.Add a comment on this line.
33
+
static_assert(sizeof(ExprT) == -1, "Conversion between these types is not supported");
It seems to me that it would be a reasonable change to not let a static_assert(false) fire in template code unless the template is actually instantiated.
Are there any show-stoppers preventing such a change?
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b647a6ab-5b4a-4f36-b392-3ab0884f274d%40isocpp.org.
Brian Bi
2018-10-19 16:05:37 UTC
Permalink
I think that it would be fine to special-case it, if you can provide a
solid rationale. Static assertions are heavy-handed because they bypass
SFINAE, and I've almost always found it preferable to avoid unconditional
static assertions for this reason. If you are going to submit a paper, be
sure to provide some good examples of when having the proposed construct be
well-formed would significantly improve the code.

My understanding is that the rule in [temp.res] is intended to prevent the
compiler from being forced to tolerate provably nonsensical constructs that
appear in a template. As far as I can tell, a static assert with false
condition is not something that would make it hard for the compiler to
continue, so this is something we could special-case.

On Fri, Oct 19, 2018 at 10:32 AM Bengt Gustafsson <
Post by Bengt Gustafsson
Well, you pointing at the rule I want to change as a motivation for not
changing the rule does not lead very far. If I wasn't proposing a change to
the language I would not be posting on this list.
There is already special handling of the boolean expression in a
static_assert compared to other constexpr boolean expressions: It causes a
compilation error if false. It can't be a big deal for a compiler to defer
the constexpr execution of this particular boolean expression to template
instantiation time if encountered in template code.
The example I gave (not by my hand) is typical of the trickery people
employ to avoid this problem, which is ugly and hard to understand.
The ideas you propose as alternatives have the drawback that they don't
allow you to affix your own error message (which was the reason to add
static_assert in the first place). Also there is no technique that works in
all contexts where static_asserts work, so you'd have to think of how to
get the effect each time.
Post by Nicolas Lesser
The problem with this is that it would special case the condition of
staric_assert.
If the condition in a template is not value-dependent, and it evaluates
to false, then the program is ill-formed. [temp.res]p8
IMO the right solution would be to not use such a static_assert. You can
always delete an overload, make an incomplete type, ... if you don't want
people using that particular instantiation.
Post by Bengt Gustafsson
It seems a recurring pattern that you try to use static_assert(false);
in template code to indicate that a template should not be instantiated,
but this currently does not work as the assert fires before the template is
// Delay evaluation of the assert by making it dependent on a template parameter
This line has a comment.Add a comment on this line.
33
+
static_assert(sizeof(ExprT) == -1, "Conversion between these types is not supported");
It seems to me that it would be a reasonable change to not let a static_assert(false) fire in template code unless the template is actually instantiated.
Are there any show-stoppers preventing such a change?
--
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b647a6ab-5b4a-4f36-b392-3ab0884f274d%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b647a6ab-5b4a-4f36-b392-3ab0884f274d%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
*Brian Bi*
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMmfjbPv%2B0hEAbx6%3DRQR-Z3gX9BuOZ3P%2BDP_FuNKwwZZ6b_oFQ%40mail.gmail.com.
Gašper Ažman
2018-10-20 11:09:14 UTC
Permalink
I can confirm I did this a lot in a previous library that I wrote.

It's a common pattern where you want to tell the user that what they are
trying to do will lead to wrong code, so you actually make a template that
matches better in the you-used-it-wrong case and gives a friendly error
(static-assert) message, instead of SFINAE-ing out and giving 48k of a
template dump that no non-expert can parse into "oh, I should have tried to
call this with a non-const object.".

You can quote me if you write this paper. I'm all for it. There are no
cases where I *don't* want to defer static_assert(false) in a template
definition to instantiation time.
Post by Brian Bi
I think that it would be fine to special-case it, if you can provide a
solid rationale. Static assertions are heavy-handed because they bypass
SFINAE, and I've almost always found it preferable to avoid unconditional
static assertions for this reason. If you are going to submit a paper, be
sure to provide some good examples of when having the proposed construct be
well-formed would significantly improve the code.
My understanding is that the rule in [temp.res] is intended to prevent the
compiler from being forced to tolerate provably nonsensical constructs that
appear in a template. As far as I can tell, a static assert with false
condition is not something that would make it hard for the compiler to
continue, so this is something we could special-case.
On Fri, Oct 19, 2018 at 10:32 AM Bengt Gustafsson <
Post by Bengt Gustafsson
Well, you pointing at the rule I want to change as a motivation for not
changing the rule does not lead very far. If I wasn't proposing a change to
the language I would not be posting on this list.
There is already special handling of the boolean expression in a
static_assert compared to other constexpr boolean expressions: It causes a
compilation error if false. It can't be a big deal for a compiler to defer
the constexpr execution of this particular boolean expression to template
instantiation time if encountered in template code.
The example I gave (not by my hand) is typical of the trickery people
employ to avoid this problem, which is ugly and hard to understand.
The ideas you propose as alternatives have the drawback that they don't
allow you to affix your own error message (which was the reason to add
static_assert in the first place). Also there is no technique that works in
all contexts where static_asserts work, so you'd have to think of how to
get the effect each time.
Post by Nicolas Lesser
The problem with this is that it would special case the condition of
staric_assert.
If the condition in a template is not value-dependent, and it evaluates
to false, then the program is ill-formed. [temp.res]p8
IMO the right solution would be to not use such a static_assert. You can
always delete an overload, make an incomplete type, ... if you don't want
people using that particular instantiation.
Post by Bengt Gustafsson
It seems a recurring pattern that you try to use static_assert(false);
in template code to indicate that a template should not be instantiated,
but this currently does not work as the assert fires before the template is
// Delay evaluation of the assert by making it dependent on a template parameter
This line has a comment.Add a comment on this line.
33
+
static_assert(sizeof(ExprT) == -1, "Conversion between these types is not supported");
It seems to me that it would be a reasonable change to not let a static_assert(false) fire in template code unless the template is actually instantiated.
Are there any show-stoppers preventing such a change?
--
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bc49018-90f2-47e4-ad3b-ed657c39d8cc%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b647a6ab-5b4a-4f36-b392-3ab0884f274d%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b647a6ab-5b4a-4f36-b392-3ab0884f274d%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
*Brian Bi*
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMmfjbPv%2B0hEAbx6%3DRQR-Z3gX9BuOZ3P%2BDP_FuNKwwZZ6b_oFQ%40mail.gmail.com
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMmfjbPv%2B0hEAbx6%3DRQR-Z3gX9BuOZ3P%2BDP_FuNKwwZZ6b_oFQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkXNRQCJkPB2CgEKYAwtNk8-qejUrMftxSX%2BwLyoAsK8bA%40mail.gmail.com.
i***@gmail.com
2018-10-20 23:02:30 UTC
Permalink
Post by Gašper Ažman
I can confirm I did this a lot in a previous library that I wrote.
It's a common pattern where you want to tell the user that what they are
trying to do will lead to wrong code, so you actually make a template that
matches better in the you-used-it-wrong case and gives a friendly error
(static-assert) message, instead of SFINAE-ing out and giving 48k of a
template dump that no non-expert can parse into "oh, I should have tried to
call this with a non-const object.".
You can quote me if you write this paper. I'm all for it. There are no
cases where I *don't* want to defer static_assert(false) in a template
definition to instantiation time.
Post by Brian Bi
I think that it would be fine to special-case it, if you can provide a
solid rationale. Static assertions are heavy-handed because they bypass
SFINAE, and I've almost always found it preferable to avoid unconditional
static assertions for this reason. If you are going to submit a paper, be
sure to provide some good examples of when having the proposed construct be
well-formed would significantly improve the code.
My understanding is that the rule in [temp.res] is intended to prevent
the compiler from being forced to tolerate provably nonsensical constructs
that appear in a template. As far as I can tell, a static assert with false
condition is not something that would make it hard for the compiler to
continue, so this is something we could special-case.
On Fri, Oct 19, 2018 at 10:32 AM Bengt Gustafsson <
Post by Bengt Gustafsson
Well, you pointing at the rule I want to change as a motivation for not
changing the rule does not lead very far. If I wasn't proposing a change to
the language I would not be posting on this list.
There is already special handling of the boolean expression in a
static_assert compared to other constexpr boolean expressions: It causes a
compilation error if false. It can't be a big deal for a compiler to defer
the constexpr execution of this particular boolean expression to template
instantiation time if encountered in template code.
The example I gave (not by my hand) is typical of the trickery people
employ to avoid this problem, which is ugly and hard to understand.
The ideas you propose as alternatives have the drawback that they don't
allow you to affix your own error message (which was the reason to add
static_assert in the first place). Also there is no technique that works in
all contexts where static_asserts work, so you'd have to think of how to
get the effect each time.
I wondering why in first place we have current behavior? What is use case
where this is useful?
One place I could image is where you write unintendly code that can't
compile because you mix up condition but in 95% cases is impossible to
catch because it depend on template parameter.
Overall for me I would prefer to change this to proposed behavior that
assertions are only trigger when template is used, this is similar do how
`assert(false)` work, even compiler see that is impossible to fulfill but
it break only when code try execute it.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ca6d27fd-91b9-49a2-8012-b53a45f3bd24%40isocpp.org.
p***@lib.hu
2018-10-20 12:49:33 UTC
Permalink
I completely agree with the motivation and the shown example looks like
another embarrassment.

Yes, it is just another entry on the list of victims from the
export-detour, but I think it stands out enough to be addressed as "special
case" until a better general way to force full instantiation-time
substitution emerges.

Is there a motivation to have a 1st phase static_assert evaluation in a
template? Maybe inside an if constexpr block.

As for specification, we already have like 4 pages describing what is
dependent in the template, adding one line for static_assert fells like a
drop in the ocean. Maybe can just use the value-dependent expression
section to state the condition part of static_assert is always such. Then
all the rest just falls in place.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fb40c88e-a16f-41e2-8361-bd98220f4809%40isocpp.org.
Loading...