Date: Tue, 12 Aug 2025 00:07:44 +0200
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);
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
> 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);
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
Received on 2025-08-11 22:07:49