C language feature in which a struct may contain as its last member an array with no specified size
C struct data types may end with a flexible array member with no specified size: typedef struct { size_t len; // there must be at least one other data member double arr[]; … Wikipedia
🌐
Wikipedia
en.wikipedia.org › wiki › Flexible_array_member
Flexible array member - Wikipedia
February 7, 2026 - C struct data types may end with a flexible array member with no specified size: typedef struct { size_t len; // there must be at least one other data member double arr[]; // the flexible array member must be last // The compiler may reserve extra padding space here, like it can between struct ...
Top answer
1 of 1
25

A flexible array member is an array without a specified size. The member has to be the last member of the struct. The actual array size is set when you allocate memory for the struct. Consequently, it only makes sense together with dynamic allocation.

Example:

#define ARRSIZE 10

struct FAM
{
    size_t sz;
    int arr[];   // Must be last struct member
};

struct FAM* fam = malloc(sizeof(struct FAM) + ARRSIZE * sizeof(int));

Now fam->arr is an array with ARRSIZE elements that you can access ussing fam->arr[index].

Further code like:

struct FAM* famA = malloc(sizeof(struct FAM) + 10 * sizeof(int));
struct FAM* famB = malloc(sizeof(struct FAM) + 1000 * sizeof(int));

will give you two pointers of the same type even though the size of the arrays differ.

So why would I use it?

Look at this code

struct FAM
{
    size_t sz;
    int arr[];
};

struct P
{
    size_t sz;
    int* p;
};

int getFAM(struct FAM* f, unsigned long x)
{
    return f->arr[x];
}

int getP(struct P* p, unsigned long x)
{
    return p->p[x];
}

It's two ways of doing "the same". One using a flexible array member, the other using a pointer.

Compiled with gcc -O2 on https://godbolt.org/ I get

which indicates that the flexible array can save you one indirection and thereby generate faster code.

It can be described like: In case of a flexible array member the array has fixed offset from a struct pointer while in case of a pointer-to-int member the array is located where the pointer value says. Consequently, in the first case the compiler can use that "known fixed offset" directly but in the second case the compiler must read the pointer value first and then read the array data.

Note: This example is for one specific system (aka compiler/cpu type). On other systems the result may differ.

Discussions

Is using flexible array members in C bad practice? - Stack Overflow
I recently read that using flexible array members in C was poor software engineering practice. However, that statement was not backed by any argument. Is this an accepted fact? (Flexible array mem... More on stackoverflow.com
🌐 stackoverflow.com
Flexible Array Members for C++
ಠ_ಠ Feature: FAMs can only be created with new This sounds highly unintuitive, as typically one would not expect new'd members to be allocated in-place. More on reddit.com
🌐 r/cpp
37
26
October 19, 2018
Are flexible array members valid in C++? - Stack Overflow
Can't you just use a std::vector member and worry about more interesting stuff? Or is this a layout issue? ... That flexible-array-member tag seems a bit... More on stackoverflow.com
🌐 stackoverflow.com
Are the flexible array member extensions of GCC mostly useless?
I can't imagine a use foe the empty struct. So that's probably useless. How does embedding these structs not at the end of a struct even work? The one extension that seems neat is static initialization of flexible array members. No idea how useful that is though. More on reddit.com
🌐 r/C_Programming
23
26
December 14, 2021
🌐
Red Hat
developers.redhat.com › articles › 2022 › 09 › 29 › benefits-limitations-flexible-array-members
The benefits and limitations of flexible array members | Red Hat Developer
August 14, 2023 - Flexible array members (FAM) is an extension of C89 standardized in C99. This article discusses how flexible array members offer convenience and improve performance and how compiler implementations
🌐
GeeksforGeeks
geeksforgeeks.org › c language › flexible-array-members-structure-c
Flexible Array Members in a structure in C - GeeksforGeeks
August 20, 2024 - Flexible Array Member(FAM) is a feature introduced in the C99 standard of the C programming language.
🌐
SEI CERT
wiki.sei.cmu.edu › confluence › x › GtcxBQ
DCL38-C. Use the correct syntax when declaring a flexible array member - SEI CERT C Coding Standard - Confluence
Flexible array members are a special type of array in which the last element of a structure with more than one named member has an incomplete array type; that is, the size of the array is not specified explicitly within the structure. This "struct hack" was widely used in practice and supported ...
Top answer
1 of 7
36

It is an accepted "fact" that using goto is poor software engineering practice. That doesn't make it true. There are times when goto is useful, particularly when handling cleanup and when porting from assembler.

Flexible array members strike me as having one main use, off the top of my head, which is mapping legacy data formats like window template formats on RiscOS. They would have been supremely useful for this about 15 years ago, and I'm sure there are still people out there dealing with such things who would find them useful.

If using flexible array members is bad practice, then I suggest that we all go tell the authors of the C99 spec this. I suspect they might have a different answer.

2 of 7
34

No, using flexible array members in C is not bad practice.

This language feature was first standardized in ISO C99, 6.7.2.1 (16). In the following revision, ISO C11, it is specified in Section 6.7.2.1 (18).

You can use them like this:

struct Header {
    size_t n  ;
    long   v[];
};
typedef struct Header Header;

size_t  n = 123; // can dynamically change during program execution
// ...
Header *h = malloc(sizeof(Header) + sizeof(long[n]));
h->n      = n;

Alternatively, you can allocate like this:

Header *h = malloc(sizeof *h + n * sizeof h->v[0]);

Note that sizeof(Header) includes eventual padding bytes, thus, the following allocation is incorrect and may yield a buffer overflow:

Header *h = malloc(sizeof(size_t) + sizeof(long[n])); // invalid!

A struct with a flexible array members reduces the number of allocations for it by 1/2, i.e. instead of 2 allocations for one struct object you need just 1. Meaning less effort and less memory occupied by memory allocator bookkeeping overhead. Furthermore, you save the storage for one additional pointer. Thus, if you have to allocate a large number of such struct instances you measurably improve the runtime and memory usage of your program (by a constant factor).

In contrast to that, using non-standardized constructs for flexible array members that yield undefined behavior (e.g. as in long v[0]; or long v[1];) obviously is bad practice. Thus, as any undefined-behaviour this should be avoided.

Since ISO C99 was released in 1999, more than 20 years ago, striving for ISO C89 compatibility is a weak argument.

🌐
Oracle
docs.oracle.com › cd › E19205-01 › 819-5265 › bjazj › index.html
D.1.8 Flexible Array Members (Sun Studio 12: C User's Guide)
Also known as the “struct hack”. Allows the last member of a struct to be an array of zero length, such as int foo[]; Such a struct is commonly used as the header to access malloced memory.
Find elsewhere
🌐
Reddit
reddit.com › r/cpp › flexible array members for c++
r/cpp on Reddit: Flexible Array Members for C++
October 19, 2018 - Flexible Array Members do not control their own allocation, like VLAs do. They will never make it into any container type, because there's no way to make it so you can do something like e.g. walk over a vector of FAM types.
🌐
TutorialsPoint
tutorialspoint.com › flexible-array-members-in-a-structure-in-c
Flexible Array Members in a Structure in C
A flexible array member is an array inside a structure without a fixed size, and its memory is allocated dynamically at runtime using malloc(), calloc(), or similar functions and it is declared using empty square brackets [].
🌐
Rip Tutorial
riptutorial.com › flexible array members
C Language Tutorial => Flexible Array Members
A structure with at least one member may additionally contain a single array member of unspecified length at the end of the structure. This is called a flexible array member:
🌐
GNU
gnu.org › software › c-intro-and-ref › manual › html_node › Flexible-Array-Fields.html
Flexible Array Fields (GNU C Language Manual)
The C99 standard adopted a more complex equivalent of zero-length array fields. It’s called a flexible array, and it’s indicated by omitting the length, like this:
🌐
Medium
light-city.medium.com › understanding-flexible-array-members-in-c-syntax-benefits-and-considerations-094e1b826d83
Understanding Flexible Array Members in C: Syntax, Benefits, and Considerations
January 5, 2024 - In C, a flexible array member is declared by defining the last data member of a structure as an array without a specified length or with a length of 0:
🌐
Google Sites
sites.google.com › site › embeddedmonologue › home › c-programming › data-alignment-structure-padding-and-flexible-array-member
embeddedmonologue - data alignment, packed/padded structure, and flexible array member (array of length zero)
Here element “d[]” is called “flexible array member” which occupy no storage space. Note that we can use "[0]" instead of "[]" to indicate a flexible array member, but that is GCC extension, not really part of C99.
🌐
GNU
gcc.gnu.org › onlinedocs › gcc › Zero-Length.html
Zero Length (Using the GNU Compiler Collection (GCC))
Although using one-element arrays this way is discouraged, GCC handles accesses to trailing one-element array members analogously to zero-length arrays. The preferred mechanism to declare variable-length types like struct line above is the ISO C99 flexible array member, with slightly different ...
🌐
SEI CERT
wiki.sei.cmu.edu › confluence › display › c › MEM33-C.++Allocate+and+copy+structures+containing+a+flexible+array+member+dynamically
MEM33-C. Allocate and copy structures containing a flexible array member dynamically - SEI CERT C Coding Standard - Confluence
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored.
Top answer
1 of 10
38

C++ was first standardized in 1998, so it predates the addition of flexible array members to C (which was new in C99). There was a corrigendum to C++ in 2003, but that didn't add any relevant new features. The next revision of C++ (C++2b) is still under development, and it seems flexible array members still aren't added to it.

2 of 10
36

C++ doesn't support C99 flexible array members at the end of structures, either using an empty index notation or a 0 index notation (barring vendor-specific extensions):

struct blah
{
    int count;
    int foo[];  // not valid C++
};

struct blah
{
    int count;
    int foo[0]; // also not valid C++
};

As far as I know, C++0x will not add this, either.

However, if you size the array to 1 element:

struct blah
{
    int count;
    int foo[1];
};

the code will compile, and work quite well, but it is technically undefined behavior. You can allocate the appropriate memory with an expression that is unlikely to have off-by-one errors:

struct blah* p = (struct blah*) malloc( offsetof(struct blah, foo[desired_number_of_elements]);
if (p) {
    p->count = desired_number_of_elements;

    // initialize your p->foo[] array however appropriate - it has `count`
    // elements (indexable from 0 to count-1)
}

So it's portable between C90, C99 and C++ and works just as well as C99's flexible array members.

Raymond Chen did a nice writeup about this: Why do some structures end with an array of size 1?

Note: In Raymond Chen's article, there's a typo/bug in an example initializing the 'flexible' array. It should read:

for (DWORD Index = 0; Index < NumberOfGroups; Index++) { // note: used '<' , not '='
  TokenGroups->Groups[Index] = ...;
}
🌐
kees
people.kernel.org › kees › bounded-flexible-arrays-in-c
Bounded Flexible Arrays in C — kees
January 23, 2023 - Such structs therefore fully describe their contents at runtime (and are called “flexible array structures” from here on). In other words, their size can be determined at run-time as: ... Teaching the compiler which struct member is associated with the count of a given flexible array member will allow -fsanitize=bounds and __builtin_dynamic_object_size() to reason about flexible array structure usage as well, covering all arrays in Linux with “known bounds”.
🌐
The Rust Programming Language
rust-lang.github.io › rust-bindgen › using-fam.html
Using Flexible Array Members - The bindgen User Guide
Rust has a set of types which are almost exact analogs for these Flexible Array Member types: the Dynamically Sized Type ("DST").
🌐
Douggregor
douggregor.net › posts › swift-for-cxx-practitioners-flexible-array-members
Swift for C++ Practitioners, Part 13: Flexible Array Members | Doug's Compiler Corner
Flexible array members are not technically part of C++, but are available as an extension in most every C++ compiler because they're common enough in C that you need them for compatibility with some C libraries.