Hi, On Mon, Aug 19, 2024 at 01:04:28PM GMT, Alejandro Colomar wrote: > On Mon, Aug 19, 2024 at 12:58:30PM GMT, Alejandro Colomar wrote: > > I have a draft for an updated proposal to WG14 (more recent than n3313). > > It has some changes to the documentation of prior art, some typo fixes, > > etc., and renames elementsof()=>nelementsof(), but the meat of the > > proposal is the same. I've also rebased it on top of the latest draft > > for C2y, which is n3301. I'll send it as a reply to this subthread. > > I've attached the PDF document of the draft n3313.1, the informal name > for an eventual revision of the n3313 proposal. I've also attached the > man(7) source. Below is a diff since n3313.
I found some issues in n3313.1 and reverted some of those.
Both the PDF paper and the man(7) source of n3313.2 are attached.
Below is a diff against 3313.1.
Cheers,
Alex
---
diff --git a/elementsof.man b/elementsof.man
index 7002553..76c882b 100644
--- a/elementsof.man
+++ b/elementsof.man
@@ -1,11 +1,11 @@
.
.
-.TH n3313.1\~ WG14 202?-??-?? ISO/IEC\~9899 "Proposal for C2y"
+.TH n3313.2\~ WG14 202?-??-?? ISO/IEC\~9899 "Proposal for C2y"
.
.
.SH Name
.
-n3313.1
+n3313.2
\-
New nelementsof() operator (v2)
.
@@ -162,47 +162,36 @@ Document prior art.
.IP \[bu]
Document backwards compatibility.
.IP \[bu]
-Document reasons for having this operator beyond the pointer safety
+Document reasons for having this operator beyond pointer safety
(which is already solved with complex macros and/or diagnostics).
.IP \[bu]
Add specific proposed changes to the draft document (based on n3220).
.PD
.RE
.TP
-n3313.1
+n3313.2
v3;
202?-??-??.
.IP
New nelementsof() operator (v3)
.IP
-n3313.1 is an informal name for a future proposal that supersedes n3313.
+n3313.2 is an informal name for a future proposal that supersedes n3313.
.RS
.IP \[bu] 3
.PD 0
Rename elementsof => nelementsof.
.IP \[bu]
+Propose an alternative shorter name: neltsof.
+.IP \[bu]
Rebase on n3301.
.IP \[bu]
Document performance problem of sizeof division.
.IP \[bu]
-Document exponential macro growth problem of magic macros.
-.IP \[bu]
Fix support for VLAs in example of NITEMS().
This needs GNU C's
.MR __builtin_types_compatible_p "" .
.IP \[bu]
-Remove concerns about double evaluation,
-since it's possible to evaluate at most once,
-by using
-.I typeof
-and GNU C's statement expression.
-That improvement also adds support for type names,
-so also remove that concern.
-.IP \[bu]
-Add support for compound literals in example of NITEMS(),
-by using a variadic macro that will accept commas in the operand.
-.IP \[bu]
-Fix typo in proposed wording.
+Fix typos, and improve wording.
.PD
.RE
.
@@ -236,25 +225,26 @@ Here's an implementation using GNU C:
) \[rs]
)
#define sizeof_array(a) (sizeof(a) + must_be(is_array(a)))
-#define sizeof_element(a) sizeof((a)[0])
-#define NITEMS(...) \[rs]
-({ \[rs]
- typeof(__VA_ARGS__) *ap_; \[rs]
- \[rs]
- sizeof_array(*ap_) / sizeof_element(*ap_); \[rs]
-})
+#define NITEMS(a) (sizeof_array(a) / sizeof((a)[0]))
.EE
.P
While diagnostics could be better,
with good helper-macro names,
they are decent.
.
+.SS Type names
+.
+This
+.IR \%NITEMS ()
+macro is not ideal,
+since it only works with expressions but not with type names.
+However, for most use cases that's enough.
+.
.SS constexpr
.
-A
-.I \%sizeof\c
--based
-implementation
+The usual
+.I \%sizeof
+division
evaluates the operand and
results in a run-time value
in cases where it wouldn't be necessary.
@@ -277,6 +267,18 @@ With a
operator,
this would result in an integer constant expression of value 7.
.
+.SS Double evaluation
+.
+With the
+.IR \%sizeof -based
+implementation from above,
+the example above causes double evaluation of
+.IR *p++ .
+It's possible to write a macro that is free of double-evaluation problems
+using a GNU statement expression and
+.IR typeof (),
+but then the macro cannot be used at file scope.
+.
.SS Diagnostics
.
Having more constant expressions would allow for increased diagnostics,
@@ -383,8 +385,6 @@ and wrap it in a macro.
Common names include:
.IP \[bu] 3
.PD 0
-\%ARRAY_SIZE()
-.IP \[bu]
\%NITEMS()
.IP \[bu]
\%NELEM()
@@ -396,8 +396,32 @@ Common names include:
\%elementsof()
.IP \[bu]
\%lengthof()
+.IP \[bu]
+\%ARRAY_SIZE()
.PD
.RE
+.P
+We can extract some patterns from these macros:
+.IP \[bu] 3
+The name derives from one of
+.RS
+.TP
+number of elements
+.TP
+size
+But there's a proposal to remove that term from the standard
+due to ambiguity with the number of bytes of an array
+.RI ( sizeof(a) ).
+.TP
+length
+This is also ambiguous in the context of strings,
+where length means the number of non-zero characters.
+.RE
+.IP \[bu]
+The name either ends in "of",
+to denote it being an operator-like macro,
+or it is in upper-case,
+to denote it being a "magic" macro.
.TP
C++
.RS
@@ -493,24 +517,34 @@ the length of a string.
"Number of elements of an array" is an expression
commonly used in the standard.
Thus,
-elements is a term that programmers are already familiar with.
+it is a term that programmers are already familiar with.
+.P
+A contraction of the proposed name would also make sense.
+.I \%neltsof
+is unused in the wild, so we could claim the name easily.
+It also has a name length similar to other existing operators.
+There's prior art in contracting names for operators,
+such as
+.IR \%alignof ,
+which stands for "alignment of".
.
.SS Backwards compatibility
.
A code search on large online platforms
-revealed that while
+revealed that
.I \%nelementsof
is in use in a single project (that we could find),
and it is semantically compatible with our proposal,
by yielding the number of elements of an array.
.P
.I \%lengthof
-is in use with incompatible semantics.
+is in use with incompatible semantics,
+so it would be more difficult to own that name.
.P
Also, while projects already use names like
.I nelts
for variable names,
-they don't use name ending in
+they don't use names ending in
.I of
for variable names.
That's more reason to use a name ending in
--
<https://www.alejandro-colomar.es/>
elementsof.pdf
Description: Adobe PDF document
elementsof.man
Description: Unix manual page
signature.asc
Description: PGP signature
