Using the sizeof operator to initialize a flexible array structure

I want to declare a structure with a flexible array element in it, and then use sizeof() on it. Prototype:

 typedef struct { uint16_t length; uint8_t array[][2]; } FLEXIBLE_t; 

Then I declare this:

 const FLEXIBLE_t test = { .length = sizeof(test), .array = { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, { 8, 9 } } }; 

Everything compiles in order (GCC), but when I look at test.length , it has a value of 2, i.e. it only considers uint16_t for length .

How can I calculate the size of the structure at compile time? It seems that the compiler is using a prototype, not a specific instance.

+8
c arrays struct sizeof flexible-array-member
source share
4 answers

GCC allows you to initialize flexible arrays as an extension: https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Zero-Length.html

However, sizeof () follows the C standard and believes that flexible arrays in structures are of zero size. In any case, when you try to use sizeof () in the structure initializer, the structure at this stage is incomplete, and the final size is not yet known. Only the size of the prototype is known with its flexible array with zero length.

The size is known at compile time, but only after the structure has been initialized. GCC __builtin_object_size() will evaluate the numeric constant in this instance, but must be called from a function because it is not always constant and therefore cannot be used in the initializer.

So .length should be assigned at runtime, but at least the assigned value compiles to a constant:

 test.length = __builtin_object_size(test, 0); 
+2
source share

sizeof ignores the element of the flexible array, since the flexible element of the array does not take up space inside the structure.

C11-ยง6.7.2.2 / 18

As a special case, the last element of the structure with more than one named element may have an incomplete array type; this is called a flexible array element. In most situations, the flexible array element is ignored. In particular, the size of the structure is as if the flexible element of the array were omitted , except that it could have a longer registration than the omission was implied. [...]

Note that the C standard does not allow initialization of a flexible array element, as in your code. It will refer to undefined behavior (see ยง6.7.2.2, paragraphs 20 and 21). Although GCC allows this as an extension:

GCC allows static initialization of flexible array elements . This is equivalent to defining a new structure containing the original structure, followed by an array of sufficient size to hold the data.

+11
source share

The flex array element does not take size into account:

... In particular, the size of the structure, as it were, a flexible element of the array was excluded, except that it may have more addition, other than omission.

In addition to the size issue, your code has undefined behavior in C. A flexible array element cannot be initialized this way. In this sense, Gcc may have an extension, but it is not portable.

+5
source share

The size returned by the sizeof() operator (almost) ignores the flexible array.

In C Standard, 6.7.2.1 Structure and Association Qualifiers , clause 18 :

As a special case, the last element of the structure with more than one named element may have an incomplete array type; this is called a flexible array element. In most situations, a flexible member array is ignored. In particular, the size of the structure is as if the flexible element of the array were omitted , except that it may have a longer registration than the omission would be implied.

+1
source share

All Articles