C++ Logo

liaison

Advanced search

Re: [isocpp-wg14/wg21-liaison] VLA notation in parameter

From: Corentin <corentin.jabot_at_[hidden]>
Date: Tue, 12 Aug 2025 08:32:15 +0200
On Tue, Aug 12, 2025 at 12:07 AM Martin Uecker via Liaison <
liaison_at_[hidden]> wrote:

> Am Montag, dem 11.08.2025 um 23:35 +0200 schrieb Jens Maurer:
> > For variable-length arrays in particular, there is a bit of history
> > in C++, from about a decade ago. The following paper contains
> > some references to the paper trail:
> >
> > https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0785r0.html
> >
> > My goal (at the time) was to standardize
> >
> > void f(int n)
> > {
> > char a[n]; // size is runtime-defined
> > }
> >
> > which works as an extension with most compilers anyway.
>
> Thanks! I remember dimly.
> >
> > There were some people in the committee who felt that
> > we should not offer a low-level facility such as the above
> > without also having a C++ abstraction offering a similar
> > feature.
> >
> > When EWG saw this paper for C++, the result (as far as
> > I remember) was that we should rather have something
> > like alloca() (i.e. a function that allocates raw stack
> > memory) and a facility to put a C++ abstraction
> > on top of the result. (We now have std::span, which
> > might help here.)
>
> This is a bit surprising as we look at "alloca()" as the
> crappy alternative (lifetimes are not properly tied to blocks).
>
> >
> > I stopped working on the proposal at this point, because
> > it seemed to deviate quite a bit from my original goal
> > to make certain (useful) C-looking code just work de jure,
> > not only de facto.
> >
> > I understand your proposal is covering a different aspect
> > of the VLA space, but there were some strong feelings back
> > then that general C-style VLAs aren't desirable for C++,
> > so I felt compelled to emphasize the limited scope of my
> > paper.
> >
> > But time has passed since then, so maybe people would be
> > more happy to embrace the function parameter aspect of VLAs
> > nowadays. However, it seems a lot of existing functions
> > take the length after the pointer, so we have a name lookup
> > issue:
> >
> > char* strncpy(char *dst, const char *src, size_t n);
> >
> > How would I write this in the new world?
>
> I mostly interested in my own numerical code, which puts
> the size before the array, and C++ interoperability is currently
> a pain. But yes, the moment we would have a solution also
> for this problem, we would also like to put it in the standard
> library in the interest of safety.
>
> WG14 is also considering forward parameter declarations
> which exist in GCC for a couple of decades. They solve
> this problem in a clean way, but are not super nice.
> We also consider trailing return types for similar reasons.
>
>
> > Should we rather
> > strive for the attribute annotation syntax that is being
> > discussed in a parallel thread?
>
> The issue is that in C we need a solution also for array
> sizes, and I am not convinced the solution proposed for
> the attributes (late parsing) really works well for those
> too. As soon as put things into the type is is visible
> from inside the language, so you need to worry about circular
> dependencies. A late-parsing design was already rejected
> by Dennis Ritchie for this reason. Another problem is
> that name lookup becomes more confusing.
>
> I wonder how C++ is dealing with this. With the new
> syntax for template functions it seems you also would
> have more situations where one might want to refer
> to other parameters. For example, you can write
>
> template<typename B>
> void foo(char a[sizeof(B)], B b);
>
> where typename B forwards declares B, but the following
> does not work:
>
> void foo(char a[sizeof(b)], auto b);
>


This has never been an issue in C++ because we use things like std::array,
std::vector, std::span
and otherwise try to avoid interfaces that would be at odds with lookup
rules.

C++ solutions have a track record of being either safer by construction or
are cheaply bound-checked
which is done across many implementations - and increasingly so.

While I appreciate that what you propose would increase compatibility with
C, it would certainly not improve safety.
I think it's fairly important that the syntax remains reflective of
semantics. C arrays parameters are not a thing,
And if anything, we should deprecate the use of array types as parameter
declarations.

Address sanitizers (tripping on access), higher level types with
preconditions, or, for C compatibility, bound check annotations
are less misleading ways to express intent, and less likely to confuse
users.






>
>
> Martin
>
>
>
> >
> > Jens
> >
> >
> >
> > On 11.08.25 22:43, Martin Uecker via Liaison wrote:
> > >
> > > Hi all,
> > >
> > > one of the main annoyances when maintaining C99 or later headers
> > > that are also consumed by C++ is that C++ does not support
> > > VLA notation for parameter and more generally variably modified types.
> > >
> > > int foo(int n, char buf[n]);
> > > int bar(int a, int b, double (*matrix)[a][b]);
> > >
> > > In C is partially integrated into BDOS, UBSan and warnings
> > > (with varying level of completeness on different compilers),
> > > so 'foo' does help find bound errors and 'bar' is also useful
> > > for numerical code.
> > >
> > >
> > > Unfortunately, C++ rejects this, so a partial workaround for
> > > 'foo' is to hide this behind a macro that expands to nothing
> > > in C++.
> > >
> > > int foo(int n, char buf[_NOCPP(n)]);
> > >
> > > 'foo' can then be used from C++ (but bounds information and
> > > related warnings you would get in C are lost).
> > >
> > >
> > > This works only at the topmost array but not for
> > >
> > > int bar(int a, int b, double (*matrix)[a][b]);
> > >
> > > which C++ AFAIK can only express using mdspan.
> > >
> > >
> > > I wonder whether the situation can be improved. At least for 'foo'
> > > it would already be a step forward if C++ could simply ignore the
> > > size expression in function declarations, maybe only for extern
> > > "C".
> > >
> > > For 'bar' it seems more difficult, but being able to parse these
> > > declaration without error would also help a lot. But it would
> > > also seem simply enough to allow calling of such function with fixed
> > > arrays, i.e. supporting
> > >
> > > extern "C" int bar(int a, int b, double (*matrix)[a][b]);
> > >
> > > void g()
> > > {
> > > double matrix[10][10];
> > > bar(10, 10, &matrix);
> > > }
> > >
> > > would only require a very superficial support for this C feature
> > > and no type system changes.
> > >
> > >
> > > What do you think?
> > >
> > >
> > > Martin
> > >
> > >
> > > _______________________________________________
> > > Liaison mailing list
> > > Liaison_at_[hidden]
> > > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > > Link to this post: http://lists.isocpp.org/liaison/2025/08/1565.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Link to this post: http://lists.isocpp.org/liaison/2025/08/1567.php
>

Received on 2025-08-12 06:32:39