This proposal is poorly motivated and deleterious, IMO.
Unfortunately it is popular / populist so acceptance looks likely.
That'll be a mistake as it is an actively damaging change.

Let me explain (at least so I can say "told you so").

The R5 revision states that EWG requested more motivation.
The new R5 motivation simply rearranges previous prose into
a sequence of bullet-points with (Clouseau style) conclusion:
 • Therefore, we should let operator[] take multiple arguments.

Please Non! What's the problem?

In C, the subscript operator returns a subobject lvalue. Good.

In C++, subscript operator overload should follow suit - it does,
mostly, but vector-of-bool returns proxy-reference instead -
this is now generally accepted as a very nasty design flaw.

In C++, multi-indexing is done with paren function-call syntax.
This is by now well established practice and is semantically fine.
Multi-indexing is indeed a functional mapping, often partial.
(P2128 protests parens "carry the wrong semantic implications").
Paren multi-indexing could just as easily (or more easily) be
extended to C, as nested C array has natural partial indexing.

Multi-indexing is most powerful when partial-indexing can return
a proxy reference, i.e. not necessarily an actual subobject.
When indexing with parens, devs know to expect a proxy result.

So, there is a clear semantic distinction with the status quo:
[i] means subobject indexing, returning a language lvalue
(i...) means multi-indexing, possibly partial, returning a proxy

This proposal adds:
[i...] what does this mean?
With operator overloading, it could mean anything at all.
The intended "motivating" use case conflates subobject vs proxy;
an infamous gotcha and dangerous pitfall.
Devs will have to carefully check the semantics.

P2128 is proposing something unprecedented - to add a new
C++ operator that has no current core language meaning.
This might constrain future language evolution, C and C++.

A more useful core language meaning might be:

    int a[4] = {1,2,3,4};

    a[1,2] = a[2,1];         // swap
    a[1,2,3,0] = a[0,1,2,3]; // it's a rotate !

Of course, this _could_ be done with the proposed C++ overload.
That's the problem - it _could_ do anything - anything at all.
It muddies what is currently a clear semantic distinction.



On Sun, Apr 25, 2021 at 2:36 PM will wray <wjwray@gmail.com> wrote:
Glad you bring this up.

"generic interoperability with C-style pointer-to-pointer arrays c"

I had a similar reaction on reading that section;
firstly confusion - what exactly does it mean,
then unease - do they know of the approach you show.

Maybe we will never know - this sentence is now gone.
There was an R4 (which still had this section), and now an R5
in which this whole section is redacted.



On Sun, Apr 25, 2021 at 3:27 AM Uecker, Martin via Liaison <liaison@lists.isocpp.org> wrote:


Just a small comment on P2128R3. There is says

"generic interoperability with C-style pointer-to-pointer
arrays c"

I assume this refers to code like this to creat
something which looks like a multi-dimensional array:

double **x = xmalloc(N * sizeof(double*));

for (int i = 0; i < N; i++) {

  x[i] = xmalloc(M * sizeof(double));

  for (int j = 0; j < M; j++)
    x[i][j] = 0.;
}


I just want to point out that this is not how we
would do this in C since at least C99. Instead
we write:

double (*x)[M] = xmalloc(sizeof(double[N][M]));

x[i][j] = 0.;

or sometimes (to more clearly differentiate
between pointers and arrays):

double (*xp)[N][M] = xmalloc(sizeof *xp);

(*xp)[i][j] = 1.;


With this, you the multi-dimensional array is
a single object and one also gets run-time bounds
checking for free if the compiler supports this.

Best,
Martin












_______________________________________________
Liaison mailing list
Liaison@lists.isocpp.org
Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
Link to this post: http://lists.isocpp.org/liaison/2021/04/0470.php