Re: Expanding the use of FLEXIBLE_ARRAY_MEMBER for declarations like foo[1]

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Michael Paquier <michael(dot)paquier(at)gmail(dot)com>
Cc: Andres Freund <andres(at)2ndquadrant(dot)com>, PostgreSQL mailing lists <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Expanding the use of FLEXIBLE_ARRAY_MEMBER for declarations like foo[1]
Date: 2015-02-19 05:58:05
Message-ID: 31479.1424325485@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Michael Paquier <michael(dot)paquier(at)gmail(dot)com> writes:
> 1-2) sizeof(ParamListInfoData) is present in a couple of places,
> assuming that sizeof(ParamListInfoData) has the equivalent of 1
> parameter, like prepare.c, functions.c, spi.c and postgres.c:
> - /* sizeof(ParamListInfoData) includes the first array element */
> paramLI = (ParamListInfo)
> palloc(sizeof(ParamListInfoData) +
> - (num_params - 1) * sizeof(ParamExternData));
> + num_params * sizeof(ParamExternData));
> 1-3) FuncCandidateList in namespace.c (thanks Andres!):
> newResult = (FuncCandidateList)
> - palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
> - + effective_nargs * sizeof(Oid));
> + palloc(sizeof(struct _FuncCandidateList) +
> + effective_nargs * sizeof(Oid));
> I imagine that we do not want for those palloc calls to use ifdef
> FLEXIBLE_ARRAY_MEMBER to save some memory for code readability even if
> compiler does not support flexible-array length, right?

These are just wrong. As a general rule, we do not want to *ever* take
sizeof() a struct that contains a flexible array: the results will not
be consistent across platforms. The right thing is to use offsetof()
instead. See the helpful comment autoconf provides:

/* 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; double
d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99
compilers. When computing the size of such an object, don't use 'sizeof
(struct s)' as it overestimates the size. Use 'offsetof (struct s, d)'
instead. Don't use 'offsetof (struct s, d[0])', as this doesn't work with
MSVC and with C++ compilers. */
#define FLEXIBLE_ARRAY_MEMBER /**/

This point is actually the main reason we've not done this change long
since. People did not feel like running around to make sure there were
no overlooked uses of sizeof().

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Noah Misch 2015-02-19 06:19:26 Re: assessing parallel-safety
Previous Message Michael Paquier 2015-02-19 05:38:10 Re: Expanding the use of FLEXIBLE_ARRAY_MEMBER for declarations like foo[1]