Discussion:
FLEXALIGNOF too pessimistic
(too old to reply)
Bruno Haible
2017-05-18 21:57:24 UTC
Permalink
Raw Message
Hi Paul,

The FLEXALIGNOF macro, from flexmember.h, in the pre-C11 or C++ case,
returns unreasonably large values. When we have a

struct { int a[64]; char c[]; }

and use FLEXALIGNOF, it will return 256. Which means that if one wants
to allocate such a struct with 4 elements of c[], one will allocate
512 bytes, when 260 bytes would be sufficient.

How about making this value smaller?

I see two approaches?
a) Cap this alignment at max_align_t.
b) Use <stdalign.h>, as in the patch below (untested).

What do you think?

Bruno


diff --git a/lib/flexmember.h b/lib/flexmember.h
index c71ea65..be8e955 100644
--- a/lib/flexmember.h
+++ b/lib/flexmember.h
@@ -17,18 +17,11 @@

Written by Paul Eggert. */

+#include <stdalign.h>
#include <stddef.h>

-/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.
- On older platforms without _Alignof, use a pessimistic bound that is
- safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.
- On newer platforms, use _Alignof to get a tighter bound. */
-
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
-# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))
-#else
-# define FLEXALIGNOF(type) _Alignof (type)
-#endif
+/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below. */
+#define FLEXALIGNOF(type) _Alignof (type)

/* 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.
diff --git a/modules/flexmember b/modules/flexmember
index 5107676..cbc259e 100644
--- a/modules/flexmember
+++ b/modules/flexmember
@@ -6,6 +6,7 @@ lib/flexmember.h
m4/flexmember.m4

Depends-on:
+stdalign

configure.ac:
AC_C_FLEXIBLE_ARRAY_MEMBER
Paul Eggert
2017-05-18 22:12:59 UTC
Permalink
Raw Message
Post by Bruno Haible
a) Cap this alignment at max_align_t.
b) Use <stdalign.h>, as in the patch below (untested).
(a) sounds reasonable. I don't think (b) will be portable enough,
because on some pre-C11 compilers the Gnulib substitute for _Alignof
does not work on structure types containing a flexible array member.
Loading...