Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A nested struct in C is a composite data type where a struct contains one or more struct variables as its members. This creates a hierarchical data model where the inner structure is fully encapsulated within the memory footprint of the outer structure, resulting in a single contiguous block of memory.

Declaration Syntax

There are two primary methods to define a nested struct: independent declaration and embedded declaration. 1. Independent Declaration (Preferred) The inner struct is defined globally or in the same scope prior to the outer struct. This allows the inner struct type to be reused elsewhere.
struct Inner {
    int x;
    int y;
};

struct Outer {
    int id;
    struct Inner nested_member; 
};
2. Embedded Declaration The inner struct is defined directly within the outer struct. If the inner struct lacks a tag (anonymous struct type), it cannot be instantiated outside of the outer struct.
struct Outer {
    int id;
    struct {
        int x;
        int y;
    } nested_member; 
};
Note: C11 introduced true anonymous structs, allowing members of an untagged, unnamed nested struct to be accessed as if they were direct members of the outer struct.
// C11 Anonymous Struct
struct Outer {
    int id;
    struct {
        int x;
        int y;
    }; // No member name provided
};

Initialization

Nested structs are initialized using nested brace-enclosed initializer lists. Modern C (C99 and later) supports designated initializers, which provide strict mapping to the nested members.
// Standard initialization
struct Outer obj1 = { 100, { 10, 20 } };

// C99 Designated initialization
struct Outer obj2 = {
    .id = 100,
    .nested_member = {
        .x = 10,
        .y = 20
    }
};

Member Access

Accessing nested members requires chaining the member access operators. The dot operator (.) is used for direct value access, while the arrow operator (->) is used when resolving through a pointer.
struct Outer obj;
struct Outer *ptr = &obj;

// Direct access chaining
obj.nested_member.x = 10;

// Pointer access chaining
ptr->nested_member.y = 20;

// C11 Anonymous struct access (no intermediate member name)
// obj.x = 10; 

Memory Layout and Alignment

A nested struct does not store a pointer to the inner struct; it expands the inner struct’s members inline. The memory allocation is strictly contiguous. The compiler applies standard Application Binary Interface (ABI) alignment and padding rules to both the inner and outer structs. The alignment requirement of the outer struct is determined by the largest alignment requirement among all its members, including the nested struct (which itself is aligned based on its largest member).
struct Inner {
    char c;      // 1 byte + 3 bytes padding
    int i;       // 4 bytes
};               // Size: 8 bytes, Alignment: 4 bytes

struct Outer {
    short s;     // 2 bytes + 2 bytes padding (to align 'nested' to 4-byte boundary)
    struct Inner nested; // 8 bytes
};               // Size: 12 bytes, Alignment: 4 bytes
Master C with Deep Grasping Methodology!Learn More