Am 14. August 2024 14:58:16 MESZ schrieb Alejandro Colomar <a...@kernel.org>: > Hi Aaron, Jens, > > On Wed, Aug 14, 2024 at 02:17:52PM GMT, Jens Gustedt wrote: > > Am 14. August 2024 13:31:19 MESZ schrieb "Ballman, Aaron" > > <aaron.ball...@intel.com>: > > > Sorry for top-posting, my work account is stuck on Outlook. :-/ > > > > > > > For a WG14 paper you should add these findings to support that choice. > > > > Another option would be for WG14 to standardize the then existing > > > > implementation with the double underscores. > > > > > > +1, it's always good to explain prior art and existing uses as part > > > of the paper. However, please also point out that C++ has a prior > > > art as well which is slightly different and very much worth > > > considering: they have one API for getting the array's rank, > > > and another for getting a specific rank's extent. This is a general > > > solution that doesn't require the programmer to have deep knowledge > > > of C's declarator syntax and how it relates to multidimensional > > > arrays. > > I have added that to my draft. I'll publish it soon as a reply to the > GCC mailing list. See below for details of what I have added for now. > > > > > > > That said, I suspect WG14 would not be keen on standardizing > > > `lengthof` without an ugly keyword given that there are plenty of other > > > uses of it that would break: > > > > > > https://sourcegraph.com/github.com/illumos/illumos-gate/-/blob/usr/src/cmd/mailx/names.c?L53-55 > > > https://sourcegraph.com/github.com/Rockbox/rockbox/-/blob/tools/ipod_fw.c?L292-294 > > > https://sourcegraph.com/github.com/OpenSmalltalk/opensmalltalk-vm/-/blob/src/spur64.stack/validImage.c?L7014-7018 > > > (and many, many others) > > What regex did you use for searching? > > I was thinking of renaming the proposal to elementsof(), to avoid > confusion between length of an array and length of a string. Would you > mind checking if elementsof() is ok?
No, not for me. I really want as to go consistently to talk about array length for this. Consistent terminology is important. > > > >> > As for the parentheses, I personally think lengthof should follow > > > >> > similar rules compared to sizeof. > > > >> > > > >> I think most people agree with this. > > > > > > > > I still don't, in particular not for standardisation. > > > > > > > > We have to remember that there are many small C compilers out there. > > > > > > Those compilers already have to handle parsing this for sizeof, so > > > that's not particularly compelling > > Agree. I suspect it will be simpler for existing compilers to follow > sizeof than to have new syntax. However, it's easy to keep it as a QoI > detail, so I've temporarily changed the wording to require parentheses, > and let implementations lift that restriction. great ! that is a reasonable approach, I think. > > > (even if we wanted to design C > > > for the lowest common denominator of implementation effort, which > > > I'm not convinced is a good approach these days). > > Off-topic, but I wish that had been the approach when a few > implementations (I suspect proprietary vendors; this was never > disclosed) rejected redefining NULL as the right thing: (void *) 0. > > I fixed one of the last free-software implementations of NULL that > expanded to 0, and nullptr would probably never have been added if WG14 > had not accepted the pressure from such horrible implementations. > > <https://github.com/cc65/cc65/issues/1823> > > > > That said, if we went with a rank/extent design, I think we'd *have* > > > to use parens because the extent interface would take two operands > > > (the array and the rank you're interested in getting the extent of) > > > and it would be inconsistent for the rank interface to then not > > > require parens. > > Prior art > C > It is common in C programs to get the number of elements of > an array via the usual sizeof division and wrap it in a > macro. Common names include: > > • ARRAY_SIZE() > • NELEM() > • NELEMS() > • NITEMS() > • NELTS() > • elementsof() > • lengthof() > > C++ > In C++, there are several standard features to determine > the number of elements of an array: > > std::size() (since C++17) > std::ssize() (since C++20) > The syntax of these is identical to the usual C > macros named above. > > It’s a bit different, since it’s a general purpose > sizing template, which works on non‐array types too, > with different semantics. > > But when applied to an array, it has the same seman‐ > tics as the macros above. > > std::extent (since C++23) > The syntax of this is quite different. It uses a > numeric index as a second parameter to determine the > dimension in which the number of elements should be > counted. > > C arrays are much simpler than C++’s many array‐like > types, and I don’t see a reason why we would need > something as complex as std::extent in C. Cer‐ > tainly, existing projects have not developed such a > macro, even if it is technically possible: > > #define DEREFERENCE(a, n) DEREFERENCE_ ## n (a, c) > #define DEREFERENCE_9(a) (*********(a)) > #define DEREFERENCE_8(a) (********(a)) > #define DEREFERENCE_7(a) (*******(a)) > #define DEREFERENCE_6(a) (******(a)) > #define DEREFERENCE_5(a) (*****(a)) > #define DEREFERENCE_4(a) (****(a)) > #define DEREFERENCE_3(a) (***(a)) > #define DEREFERENCE_2(a) (**(a)) > #define DEREFERENCE_1(a) (*(a)) > #define DEREFERENCE_0(a) ((a)) > #define extent(a, n) nitems(DEREFERENCE(a, n)) > > If any project needs that syntax, they can implement > their own trivial wrapper macro, as demonstrated > above. > > Existing prior art in C seems to favour a design that fol‐ > lows the syntax of other operators like sizeof. > > > I think that this argument goes too short. E. g. implementation that > > already have compound expressions (or lambdas ;-) may provide a > > quality implementation using `static_assert` and `typeof` alone, and > > don't have to touch their compiler at all. > > > > We should not impose an implementation in the language where doing it > > in a header can be completely sufficient. > > I have concerns about a libc (or a predefined macro) implementation: > the sizeof division causes double evaluation with any VLAs, while my > implementation for GCC has less cases of evaluation, and when it needs > to evaluate, it only does it once. It would be hard to find a good > wording that would allow an implementation to implement this as a macro. No, we should not allow double evaluation. putting this in a `({ })` and doing a `typedef typeof(X) _my_type;` with the macro parameter `X` at the beginning completely avoids double evaluation. So quality implantations are possible, but perhaps differently and with other builtins than we are imagining. Don't impose the view of one particular implementation onto others. Somewhere was brought in an argument with `offsetof`. This is exactly what we need. Implementations being able to start with a simple solution (as everybody did in the beginning of `offsetof` ), and improve that implementation at their pace when they are ready for it. > > constexpr > The usual sizeof division evaluates the operand and results in a > run‐time value in cases where it wouldn’t be necessary. If the > top‐level array number of elements is determined by an integer > constant expression, but an internal array is a VLA, sizeof must > evaluate: > > int a[7][n]; > int (*p)[7][n]; > > p = &a; > nitems(*p++); > > With a elementsof operator, this would result in an integer con‐ > stant expression of value 7. > > Double evaluation > With the sizeof‐based implementation from above, the example from > above causes double evaluation of *p++. > > > Plus, implementing as a macro in a header (probably <stddef.h>) makes > > also a feature test, for those applications that already have > > something similar. > > This is interesting. But I think an implementation could just > > #define lengthof lengthof > > to provide a feature-test macro. Sure, but leave some slack to implementations to do this in a way that's best for them > > this was basically what we did for `unreachable` and I think it worked > > out fine. I still think that the different options that we had there can be used to ask the right questions for WG14. Jens -- Jens Gustedt - INRIA & ICube, Strasbourg, France