I need a way in a C preprocessor #if to test if a value will create a 0-size array

This problem can be solved without any need for preprocessor with a help of anonymous structs introduced in C11.

Define the flash type as a union that contains members embedded into anonymous struct. Make char _pad[0x10000] the other member of the union to force the total size of the introduced type.

typedef union {
    struct {
        uint16_t firstElement;
        uint8_t  secondElementArray[32];
        float thirdElement;
    };
    char _pad[0x10000];
} flash_t;

This solution is robust to any modifications to the layout of the struct members. Moreover, this avoids problem of defining zero-length array that is technically forbidden by C standard (though allowed in GCC). Additionally, one can add a static assert to check if the maximal size of the flash got overflown.

Example program:

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

typedef union {
    struct {
        uint16_t firstElement;
        uint8_t  secondElementArray[32];
        float thirdElement;
        // int kaboom[20000]; // will trigger assert if uncommented
    };
    char _pad[0x10000];
} flash_t;

_Static_assert(sizeof(flash_t) == 0x10000, "Oops, flash_t got too large");

int main() {
    flash_t flash;
    printf("offsetof(flash.firstElement) = %zi\n", offsetof(flash_t, firstElement));
    printf("offsetof(flash.secondElementArray) = %zi\n", offsetof(flash_t, secondElementArray));
    printf("offsetof(flash.thirdElement) = %zi\n", offsetof(flash_t, thirdElement));
    printf("sizeof(flash) = %zi\n", sizeof flash);
    return 0;
}

Produces expected output:

offsetof(flash.firstElement) = 0
offsetof(flash.secondElementArray) = 2
offsetof(flash.thirdElement) = 36
sizeof(flash) = 65536

EDIT

  • As suggested in the comment the union member _pad could be renamed to _rawData because semantics of _pad differs from pad in the question.

  • If a member pad within the type is required then one could add it as a flexible member at the end of anonymous struct.

typedef union { struct { ...; uint8_t pad[]; }; char _rawData[0x10000]; } flash_t;

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)