>From eb7977e908bd3b2a1367ab2871647e76055b4ba0 Mon Sep 17 00:00:00 2001 From: Paul Eggert 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 + 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