最近在看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初始化
...
}
可见,标记化结构初始化语法,可以提高代码的灵活性和可扩展性。