__TRAILING_OVERLAP(9)
π
__TRAILING_OVERLAP (9) β Kernel API Manual
okay bestie so this one is from the Kernel API Manual and it's genuinely such a slay little macro, like it's giving "let me hold two things in the same spot" and honestly? iconic. let me walk you through it π«Ά
β¨ NAME β¨
__TRAILING_OVERLAP β overlaps a flexible-array member with trailing members. that's it, that's the whole vibe π
β¨ SYNOPSIS β¨
__TRAILING_OVERLAP (TYPE , NAME , FAM , ATTRS , MEMBERS );
like yes she takes five things and she makes magic, no cap β¨
πΈ ARGUMENTS πΈ
TYPEβ the flexible structure type name, and yes girl you gotta include thestructkeyword, don't forget it or she will NOT know what you mean πNAMEβ the name for the variable you're defining, like the name of the actual new thing πFAMβ the flexible-array member insideTYPE. your fam in the struct sense, your ride-or-die array πATTRSβ any struct attributes, and usually this is just empty, like an empty group chat, totally fine π¦MEMBERSβ the trailing overlapping members, the little extras that want to live in the same square footage π
π₯ DESCRIPTION π₯
So what she literally does is: she creates a union between a flexible-array member (that's the FAM, iykyk) in a struct and a set of additional members that would otherwise follow it. two views, one storage, main character energy fr fr π
β οΈ okay warning time, bestie, listen to me: because this helper enclosesTYPE NAMEandMEMBERSin the same union, designated initializers forMEMBERSmay overwrite portions you previously initialized throughNAME. like they're literally sharing the same lockers and somebody is gonna get their stuff yeeted π
For example:
struct flex {
size_t count;
u8 fam[];
};
struct composite {
...
__TRAILING_OVERLAP(struct flex, flex, fam, __packed,
u8 data;
);
} __packed;
static struct composite comp = {
.flex = {
.count = 1,
},
.data = 2,
};
In the example above, .flex and .data initialize different views of the same union storage. And since .data is initialized last, it may overwrite portions previously initialized through .flex β which can lead to .flex.count being zeroed out. bestie that's your count just... gone. poof. zeroed. π
A couple of alternatives are shown below. she gave us options, we love a flexible queen π
π a) keep it one-view
Initialize only one view of the overlapped storage and assign the rest at runtime:
static struct composite comp = {
.flex = {
.count = 1,
},
};
static void foo(void)
{
comp.data = 2;
...
}
π b) runtime assignments only
Alternatively, replace designated initializers with runtime assignments:
static void foo(void)
{
struct composite comp;
comp.flex.count = 1;
comp.data = 2;
...
}
Compiler Explorer test code: https://godbolt.org/z/voM4E36dT β go poke at it, it's literally right there π§
For another example of the above see commit 5e54510a9389 ("acpi: nfit: intel: avoid multiple -Wflex-array-member-not-at-end warnings")
Link: https://git.kernel.org/linus/5e54510a9389caa9
π SEE ALSO π
Kernel file ./include/linux/stddef.h and her whole friend group: sizeof_field(9), offsetofend(9), struct_group(9), struct_group_attr(9), struct_group_tagged(9), DECLARE_FLEX_ARRAY(9), TRAILING_OVERLAP(9) β
and that's the page, bestie!! sign-off time: this gorgeous thing lives over in ./include/linux and the date on it is October 2026 β so yeah, she's from the future and she's still serving πβ¨ no cap, go forth and overlap responsibly π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms