代码之家  ›  专栏  ›  技术社区  ›  MysteryMoose

GCC下故意忽略初始化器警告中的过量元素

  •  0
  • MysteryMoose  · 技术社区  · 7 月前

    我试图滥用静态初始化来构建一个没有任何运行时初始化的菜单树:

    typedef struct {
        menu_entry_t entry;
        uint16_t can_loop:1;
        uint16_t sz:15;
        uint32_t entries[0];
    } __attribute__((packed)) menu_data_t;
    
    static menu_data_t menu_list[] = {
        {
            .entry = MENU_COIL_POWER,
            .can_loop = 0,
            .sz = 5,
            .entries = {
                RGB(0x0F, 0x0A, 0x00),
                RGB(0x1F, 0x15, 0x00),
                RGB(0x3F, 0x29, 0x00),
                RGB(0x7F, 0x53, 0x00),
                RGB(0xFF, 0xA5, 0x00),
            }
        },
        {
            .entry = MENU_LED_MODE,
            .can_loop = 0,
            .sz = 3,
            .entries = {
                RGB(63, 63, 0),
                RGB(127, 127, 0),
                RGB(255, 255, 0),
            }
        },
        // ...
    };
    

    这会构建,但GCC会抱怨初始化 entries 子阵列:

    warning: excess elements in array initializer
    

    我该如何消除这一具体警告?我完全知道它的生成是因为我已经声明 uint32_t entries[0] 数组大小为零。这是我过去通过以下方式动态利用的一种范式 malloc(sizeof(menu_data_t) + num_entries * sizeof(uint32_t)) ;我现在只是试图静态地做这件事。

    所以,简而言之, 如何在初始化器警告中禁用GCC的多余元素 (最好是可以喂入的东西 #pragma GCC diagnostic ignored "..." )?搜索GCC的文档似乎没有明确的 -W 它的标志(或者,至少,它被称为意想不到的东西)?

    一些相关研究:

    1 回复  |  直到 7 月前
        1
  •  1
  •   KamilCuk    7 月前

    看着 GCC force warning to be an error: excess elements in array initializer 以及gcc源代码,没有选项可以静音警告。

    注:这是一个XY问题。它询问如何消除编译器警告。相反,考虑研究如何正确初始化具有灵活数组长度的结构数组。

    这个问题还包含一个错误的前提。所有“多余”的数据都被忽略了,它们是 存储在任何地方,可以从源代码中删除。

    lenght zero数组是gcc扩展。如gcc文档所述 https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html 更喜欢C99语法。

    底线, 忽略你的问题 ,我认为不存在用灵活的数组模因静态初始化结构数组的方法。我只做指针,忘记它。注意:指针本身是const,可以存储在ROM中。

    #include <stdint.h>
    typedef enum { MENU_COIL_POWER, MENU_LED_MODE } menu_entry_t;
    #define RGB(a,b,c) a
    typedef struct {
        menu_entry_t entry;
        uint16_t can_loop:1;
        uint16_t sz:15;
        uint32_t entries[];
    } menu_data_t;
    static menu_data_t a = {
        .entry = MENU_COIL_POWER,
        .can_loop = 0,
        .sz = 5,
        .entries = {
            RGB(0x0F, 0x0A, 0x00),
            RGB(0x1F, 0x15, 0x00),
            RGB(0x3F, 0x29, 0x00),
            RGB(0x7F, 0x53, 0x00),
            RGB(0xFF, 0xA5, 0x00),
        }
    };
    static menu_data_t b = {
        .entry = MENU_LED_MODE,
        .can_loop = 0,
        .sz = 3,
        .entries = {
            RGB(63, 63, 0),
            RGB(127, 127, 0),
            RGB(255, 255, 0),
        }
    };
    static menu_data_t *const menu_list[] = {&a, &b};
    

    如果这对你和你来说还不够 真正地 请务必注意,您将编写一个程序来生成 字节 它们组成数组或自己管理组成数组的字节,并使用反序列化或抽象将字节中的数据转换为C编程语言。例如,在X86计算机上,以下代码输出 3 7f7f :

    #include <stdint.h>
    #include <stdio.h>
    enum { MENU_COIL_POWER, MENU_LED_MODE };
    typedef uint16_t menu_entry_t;
    #define RGB(a,b,c)  /*little endian*/ a,b,c,0
    typedef struct {
        menu_entry_t entry;
        uint16_t can_loop:1;
        uint16_t sz:15;
        uint32_t entries[];
    } __attribute__((packed)) menu_data_t;
    #define MAKE_MENU_DATA(entry, can_loop, sz)   \
        /* assuming some bit order and endianess of target platform */ \
        entry, entry >> 8, sz << 1 | can_loop, sz >> 7
    static _Alignas(menu_data_t) unsigned char menu_data[] = {
        MAKE_MENU_DATA(MENU_COIL_POWER, 0, 5),
        RGB(0x0F, 0x0A, 0x00),
        RGB(0x1F, 0x15, 0x00),
        RGB(0x3F, 0x29, 0x00),
        RGB(0x7F, 0x53, 0x00),
        RGB(0xFF, 0xA5, 0x00),
        MAKE_MENU_DATA(MENU_LED_MODE, 0, 3),
        RGB(63, 63, 0),
        RGB(127, 127, 0),
        RGB(255, 255, 0),
    };
    menu_data_t *get_menu_data(unsigned i) { 
        char *pnt = menu_data;
        while (1) {
            menu_data_t *tmp = (void*)pnt;
            if (!i--) return tmp;
            pnt += sizeof(menu_data_t) + sizeof(uint32_t) * tmp->sz;
        }
    }
    int main() {
        printf("%d %x\n", get_menu_data(1)->sz, get_menu_data(1)->entries[1]);
    }
    
    推荐文章