Date: Tue, 16 Jul 2024 16:18:21 -0400
Hi Danil,
Your proposal seems poorly motivated.
I absolutely 100% agree with you that N1984's motivation for not providing
`auto x[] = {1,2,3}` was also insufficient. You are absolutely correct that
int x[] = {1,2,3};
auto y[] = x;
clearly cannot mean "copy the array `x` into a new array `y`," because of
course it would do array-to-pointer decay, and of course it's ill-formed.
So N1984 page 6 is pretty silly, by modern standards. However, we should
also remember that N1984 was from 2006, when they were literally *inventing*
the rules for `auto`. So things that are "obvious" today about how `auto`
interacts with declaration syntax, might not have been obvious, nor even
logically necessary, back in 2006.
Also, I suspect that N1984 had a typo in their last example:
int x[5];
auto y[] = x; // would this be allowed and y : int * ?
I think what they meant here was
int x[5];
auto y[] = {x}; // would this be allowed and y : int * ?
and the answer in 2024 is obviously that if we allow that, then `auto y[]`
must be deduced as `int *y[1]`. (But remember this might not have been
obvious 20 years ago.)
But just because N1984's *rationale* is bad, doesn't mean that their
*decision* is necessarily bad. (Maybe the syntax is so confusing, and so
useless in practice anyway, that it makes sense to ban it. It keeps the
language simple, and perhaps even protects the programmer against silly
typos.) You need to defeat not just N1984's silly rationale, but the *strongest
<https://en.wikipedia.org/wiki/Straw_man#Steelmanning> rationale anyone can
think of* for the status quo.
And even if N1984 made a bad *decision,* that doesn't mean that *reversing
their decision today* would be a good thing. For example, we know that
C++98 decided badly when they made constructors `explicit(false)` by
default. But we don't propose to change that today, because it would be too
disruptive. Any change (especially an explicit reversal of a previous
decision) will be disruptive — that's a cost. You need to demonstrate that
the cost is outweighed by a *positive benefit*. Your paper lacks any
discussion of positive benefits. You have a section titled "Motivation,"
but it doesn't provide any motivation at all; it says that "we can do
this," but it never once says that "we should do this."
You need to consider examples like:
auto a[] = {1,'a'}; // is this int[2], char[2], pair<int,char>,
ill-formed, or what?
int b[] = {1,2};
auto c[]{b}; // is this int*[1], ill-formed, or what? Notice the lack
of `=` here
auto d[][] = {{1,2}, {3,4}}; // is this int[2][2], ill-formed, or what?
auto e[](1,2); // is this int[2], ill-formed, or what?
auto f[3] = {1,2}; // is this int[3], ill-formed, or what? Notice the
third element is uninitialized
Your proposed wording makes the Standard longer and more complicated. You
need to explain the benefit that outweighs this obvious cost.
To be clear: I'm 75% confident that you cannot name such a benefit, and
therefore you should abandon this complicated and unnecessary. proposal.
HTH,
–Arthur
On Tue, Jul 16, 2024 at 2:47 PM Zhihao Yuan via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Tuesday, July 16th, 2024 at 5:14 AM, Данил Сидорук via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> I got that we can't just remove `T shall not be an array type` and make
> few changes in the next paragraph. Cause we can't deduce array type using
> the rules of template argument deduction from a function call with
> initializer list:
> #include <cstdio>
> template <class U>
> void f(U(&u)[]) {}
> int main() {
> f({1, 2, 3, 4, 5}); // Doesn't work
> }
>
>
> The three major compilers agree that calling
>
> template <class U>
> void f(U(&&u)[]);
>
> with that initializer list works. It seems that U(&)[]
> does not work only because it cannot bind to an
> array rvalue.
>
> --
> Zhihao
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Your proposal seems poorly motivated.
I absolutely 100% agree with you that N1984's motivation for not providing
`auto x[] = {1,2,3}` was also insufficient. You are absolutely correct that
int x[] = {1,2,3};
auto y[] = x;
clearly cannot mean "copy the array `x` into a new array `y`," because of
course it would do array-to-pointer decay, and of course it's ill-formed.
So N1984 page 6 is pretty silly, by modern standards. However, we should
also remember that N1984 was from 2006, when they were literally *inventing*
the rules for `auto`. So things that are "obvious" today about how `auto`
interacts with declaration syntax, might not have been obvious, nor even
logically necessary, back in 2006.
Also, I suspect that N1984 had a typo in their last example:
int x[5];
auto y[] = x; // would this be allowed and y : int * ?
I think what they meant here was
int x[5];
auto y[] = {x}; // would this be allowed and y : int * ?
and the answer in 2024 is obviously that if we allow that, then `auto y[]`
must be deduced as `int *y[1]`. (But remember this might not have been
obvious 20 years ago.)
But just because N1984's *rationale* is bad, doesn't mean that their
*decision* is necessarily bad. (Maybe the syntax is so confusing, and so
useless in practice anyway, that it makes sense to ban it. It keeps the
language simple, and perhaps even protects the programmer against silly
typos.) You need to defeat not just N1984's silly rationale, but the *strongest
<https://en.wikipedia.org/wiki/Straw_man#Steelmanning> rationale anyone can
think of* for the status quo.
And even if N1984 made a bad *decision,* that doesn't mean that *reversing
their decision today* would be a good thing. For example, we know that
C++98 decided badly when they made constructors `explicit(false)` by
default. But we don't propose to change that today, because it would be too
disruptive. Any change (especially an explicit reversal of a previous
decision) will be disruptive — that's a cost. You need to demonstrate that
the cost is outweighed by a *positive benefit*. Your paper lacks any
discussion of positive benefits. You have a section titled "Motivation,"
but it doesn't provide any motivation at all; it says that "we can do
this," but it never once says that "we should do this."
You need to consider examples like:
auto a[] = {1,'a'}; // is this int[2], char[2], pair<int,char>,
ill-formed, or what?
int b[] = {1,2};
auto c[]{b}; // is this int*[1], ill-formed, or what? Notice the lack
of `=` here
auto d[][] = {{1,2}, {3,4}}; // is this int[2][2], ill-formed, or what?
auto e[](1,2); // is this int[2], ill-formed, or what?
auto f[3] = {1,2}; // is this int[3], ill-formed, or what? Notice the
third element is uninitialized
Your proposed wording makes the Standard longer and more complicated. You
need to explain the benefit that outweighs this obvious cost.
To be clear: I'm 75% confident that you cannot name such a benefit, and
therefore you should abandon this complicated and unnecessary. proposal.
HTH,
–Arthur
On Tue, Jul 16, 2024 at 2:47 PM Zhihao Yuan via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Tuesday, July 16th, 2024 at 5:14 AM, Данил Сидорук via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> I got that we can't just remove `T shall not be an array type` and make
> few changes in the next paragraph. Cause we can't deduce array type using
> the rules of template argument deduction from a function call with
> initializer list:
> #include <cstdio>
> template <class U>
> void f(U(&u)[]) {}
> int main() {
> f({1, 2, 3, 4, 5}); // Doesn't work
> }
>
>
> The three major compilers agree that calling
>
> template <class U>
> void f(U(&&u)[]);
>
> with that initializer list works. It seems that U(&)[]
> does not work only because it cannot bind to an
> array rvalue.
>
> --
> Zhihao
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2024-07-16 20:18:35