Edge case with offsetof
I've been trying out using offsetof to calculate the size of structures with flexible array members, and CompCert appears to be the only compiler that fails this test case (where flexible array members are supported at all). I'm not sure if it should fail, but you might want to know.
Note that I'm not 100% whether this code is supposed to work according to the standard.
Test case code
#include <stddef.h>
#include <stdlib.h>
typedef struct {
int a;
int b;
double c;
double d;
} Element;
typedef struct {
size_t used;
size_t capacity;
Element items[]; /* Flexible array member. */
} Container;
Container* bar(
unsigned someNumber)
{
return malloc(offsetof(Container, items[someNumber]));
/* Other initialisation omitted. */
}
Expected outcome
I'd expect to get a function that allocates memory of the stack where the size of the FAM is large enough to take someNumber elements.
What I got
(Running on godbolt with version 3.12)
<source>:20: error: array element designator is not an integer constant expression
1 error detected.
That's an interesting edge case, indeed !
The C11 standard says:
offsetof(type, member-designator) which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that given static type t; then the expression &(t.member-designator) evaluates to an address constant.
Note the "integer constant" and "address constant" clauses. I don't think this condition is met in your example. So, I think CompCert is not wrong to reject it. But it is surprising indeed, since the naive implementation of offsetof(ty, memb) as
(size_t) (char *) (((ty *) NULL)->memb)
seems to work even if memb contains a non-constant array reference.