Documentation/process/deprecated.rst

Source file repositories/reference/linux-study-clean/Documentation/process/deprecated.rst

File Facts

System
Linux kernel
Corpus path
Documentation/process/deprecated.rst
Extension
.rst
Size
18081 bytes
Lines
412
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct something {
                size_t count;
                struct foo items[1];
        };

This led to fragile size calculations via sizeof() (which would need to
remove the size of the single trailing element to get a correct size of
the "header"). A `GNU C extension <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_
was introduced to allow for zero-length arrays, to avoid these kinds of
size problems::

        struct something {
                size_t count;
                struct foo items[0];
        };

But this led to other problems, and didn't solve some problems shared by
both styles, like not being able to detect when such an array is accidentally
being used _not_ at the end of a structure (which could happen directly, or
when such a struct was in unions, structs of structs, etc).

C99 introduced "flexible array members", which lacks a numeric size for
the array declaration entirely::

        struct something {
                size_t count;
                struct foo items[];
        };

This is the way the kernel expects dynamically sized trailing elements
to be declared. It allows the compiler to generate errors when the
flexible array does not occur last in the structure, which helps to prevent
some kind of `undefined behavior
<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_
bugs from being inadvertently introduced to the codebase. It also allows
the compiler to correctly analyze array sizes (via sizeof(),
`CONFIG_FORTIFY_SOURCE`, and `CONFIG_UBSAN_BOUNDS`). For instance,
there is no mechanism that warns us that the following application of the
sizeof() operator to a zero-length array always results in zero::

        struct something {
                size_t count;
                struct foo items[0];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
        instance->count = count;

        size = sizeof(instance->items) * instance->count;
        memcpy(instance->items, source, size);

At the last line of code above, ``size`` turns out to be ``zero``, when one might
have thought it represents the total size in bytes of the dynamic memory recently
allocated for the trailing array ``items``. Here are a couple examples of this
issue: `link 1
<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
`link 2
<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
Instead, `flexible array members have incomplete type, and so the sizeof()
operator may not be applied <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
so any misuse of such operators will be immediately noticed at build time.

With respect to one-element arrays, one has to be acutely aware that `such arrays
occupy at least as much space as a single object of the type
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
hence they contribute to the size of the enclosing structure. This is prone
to error every time people want to calculate the total size of dynamic memory
to allocate for a structure containing an array of this kind as a member::

Annotation

Implementation Notes