标记化结构初始化

最近在看NVDLA的runtime代码,发现代码里面对结构体的初始化,在成员变量前面加了一个点,感觉很奇怪。一查发现,这又是一个知识点的盲区。遂做个简单整理。

在对结构体初始化是,通常使用C中常见的按声明顺序初始化的语法。这里在初始化时,在成员变量前加一个点是一种C99的语法,称为标记化结构初始化。
下面,以代码为例,说明它的特点。

runtime程序中对dla_engine的结构体声明如下,声明位置在dla_engine.h文件中。dla_engine是完成一个inference任务需要的所有变量的总和。

struct dla_engine {
    struct dla_task *task;
    struct dla_config *config_data;
    struct dla_network_desc *network;
    struct dla_processor processors[DLA_OP_NUM];

    uint16_t num_proc_hwl;
    int32_t status;
    uint32_t stat_enable;

    void *driver_context;
};

在dla_engine中包含了六种dla_processor,每个dla_processor中又包含了两组寄存器组,操作类型以及operation相关的函数指针等成员。

struct dla_processor {
    const char *name;
    uint8_t op_type;
    uint8_t consumer_ptr;
    uint8_t roi_index;
    uint8_t group_status;
    uint8_t rdma_status;
    uint8_t last_group;

    struct dla_common_op_desc *tail_op;
    struct dla_processor_group groups[DLA_NUM_GROUPS];
    union dla_stat_container *stat_data_desc;

    int32_t (*is_ready)(struct dla_processor *processor,
                  struct dla_processor_group *group);
    int32_t (*enable)(struct dla_processor_group *group);
    int32_t (*program)(struct dla_processor_group *group);
    void (*set_producer)(int32_t group_id, int32_t rdma_id);
    void (*dump_config)(struct dla_processor_group *group);
    void (*rdma_check)(struct dla_processor_group *group);
    void (*get_stat_data)(struct dla_processor *processor,
                struct dla_processor_group *group);
    void (*dump_stat)(struct dla_processor *processor);
};

定义一个static的dla_engine,只对processors成员初始化,这说明标记化结构化初始化语法可以指定初始化的成员,并且初始化的成员可以缺省,即只初始化某个或某些成员。既然可以缺省初始化,那么肯定支持不按照声明顺序初始化成员。同时,这种初始化语法可以嵌套。

static struct dla_engine engine = {
    .processors[DLA_OP_CONV] = {
        .name = "Convolution",
        .op_type = DLA_OP_CONV,
        .program = dla_conv_program,//初始化函数指针
        .enable = dla_conv_enable,
        .set_producer = dla_conv_set_producer,
        .is_ready = dla_conv_is_ready,
        .dump_config = dla_conv_dump_config,
        .rdma_check = dla_conv_rdma_check,
        .get_stat_data = dla_conv_stat_data,
        .dump_stat = dla_conv_dump_stat,
        .consumer_ptr = 0,
        .roi_index = 0,
        .group_status = 0,
        .rdma_status = 0,
        .last_group = 0,
        .groups[0] = {//初始化寄存器组
            .id = 0,
            .rdma_id = 0,
            .active = 0,
            .events = 0,
            .roi_index = 0,
            .is_rdma_needed = 0,
            .lut_index = -1,
            .operation_desc = &operation_desc[DLA_OP_CONV][0],
            .surface_desc = &surface_desc[DLA_OP_CONV][0],
        },
        .groups[1] = {
            .id = 1,
            .rdma_id = 0,
            .active = 0,
            .events = 0,
            .roi_index = 0,
            .is_rdma_needed = 0,
            .lut_index = -1,
            .operation_desc = &operation_desc[DLA_OP_CONV][1],
            .surface_desc = &surface_desc[DLA_OP_CONV][1],
        },
    },
    .processors[DLA_OP_BDMA] = {
        ...
    }
    //剩余四种processors初始化
    ...
}

可见,标记化结构初始化语法,可以提高代码的灵活性和可扩展性。

你可能感兴趣的:(C++)