On 5/24/19 4:33 PM, Bruno Haible wrote:
You found the right words now :) - I would expect to see such
explanations in the .h file, not in the .m4 file.
I gave that a shot by installing the attached.
>From eb7977e908bd3b2a1367ab2871647e76055b4ba0 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 24 May 2019 17:31:34 -0700
Subject: [PATCH] flexmember: update comments again

* lib/flexmember.h, m4/flexmember.m4: Improve comments further.
---
 ChangeLog        |  3 +++
 lib/flexmember.h | 25 ++++++++++++++++++++-----
 m4/flexmember.m4 | 12 +++---------
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index efa81e2ae..2cd6145c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2019-05-24  Paul Eggert  <egg...@cs.ucla.edu>
 
+	flexmember: update comments again
+	* lib/flexmember.h, m4/flexmember.m4: Improve comments further.
+
 	flexmember: update comment
 	* m4/flexmember.m4 (AC_C_FLEXIBLE_ARRAY_MEMBER): Improve comment.
 
diff --git a/lib/flexmember.h b/lib/flexmember.h
index 8e79bce03..431bec11e 100644
--- a/lib/flexmember.h
+++ b/lib/flexmember.h
@@ -33,11 +33,26 @@
 # define FLEXALIGNOF(type) _Alignof (type)
 #endif
 
-/* Upper bound on the size of a struct of type TYPE with a flexible
-   array member named MEMBER that is followed by N bytes of other data.
-   This is not simply sizeof (TYPE) + N, since it may require
-   alignment on unusually picky C11 platforms, and
-   FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.
+/* Yield a properly aligned upper bound on the size of a struct of
+   type TYPE with a flexible array member named MEMBER that is
+   followed by N bytes of other data.  The result is suitable as an
+   argument to malloc.  For example:
+
+     struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; };
+     struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char)));
+
+   FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N),
+   since FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.  Nor is
+   it simply (offsetof (TYPE, MEMBER) + N), as that might yield a size
+   that causes malloc to yield a pointer that is not properly aligned
+   for TYPE; for example, if sizeof (int) == alignof (int) == 4,
+   malloc (offsetof (struct s, d) + 3 * sizeof (char)) is equivalent
+   to malloc (7) and might yield a pointer that is not a multiple of 4
+   (which means the pointer is not properly aligned for struct s),
+   whereas malloc (FLEXSIZEOF (struct s, d, 3 * sizeof (char))) is
+   equivalent to malloc (8) and must yield a pointer that is a
+   multiple of 4.
+
    Yield a value less than N if and only if arithmetic overflow occurs.  */
 
 #define FLEXSIZEOF(type, member, n) \
diff --git a/m4/flexmember.m4 b/m4/flexmember.m4
index ef6373df2..c245ab025 100644
--- a/m4/flexmember.m4
+++ b/m4/flexmember.m4
@@ -34,16 +34,10 @@ AC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER],
     AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [],
       [Define to nothing if C supports flexible array members, and to
        1 if it does not.  That way, with a declaration like 'struct s
-       { int n; char d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack
+       { int n; short d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack
        can be used with pre-C99 compilers.
-       Use 'FLEXSIZEOF (struct s, d, N)' to calculate the size in bytes
-       of such a struct containing an N-element array, as both
-       'sizeof (struct s) + N * sizeof (char)' and
-       'offsetof (struct s, d) + N * sizeof (char)'
-       might compute a size that can cause malloc to align storage
-       improperly, even in C11.
-       Don't use 'offsetof (struct s, d@<:@0@:>@)', as this doesn't work with
-       MSVC and with C++ compilers.])
+       Use 'FLEXSIZEOF (struct s, d, N * sizeof (short))' to calculate
+       the size in bytes of such a struct containing an N-element array.])
   else
     AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1])
   fi
-- 
2.21.0

Reply via email to