我有以下C代码,该代码创建描述FIFO的结构,并分别定义一个数组以保存该FIFO的实际数据。这是我正在编写的基本I2C / TWI驱动程序的一部分,最好是更简洁地执行此操作,例如使用以大小为参数的函数。
twi_fifo_t fifo;
twi_entry_t fifodata[64];
fifo.push = 0;
fifo.pull = 0;
fifo.next_cmd = 0;
fifo.size_mask = ~(0xFFFF<<6);
fifo.data = fifodata;
但是,我希望对它们进行静态分配,因为没有可预见的原因在运行时创建,销毁或更改它们。
我的理解是,如果我在一个函数中创建了FIFO和数据数组,我将需要使用malloc()分配它们,因为它们的位置无法在编译时确定。这似乎需要一个宏,它会导致第二段代码。
#define twi_make_fifo(name, size)\
twi_fifo_t name;\
twi_entry_t name##_data[1<<size];\
name.push = 0;\
name.pull = 0;\
name.next_cmd = 0;\
name.size_mask = ~(0xFFFF<<size);\
name.data = name##_data;
宏解决方案似乎有点令人讨厌,是否有一些明显的方法可以简化我遗忘的操作?
答案 0 :(得分:3)
如果FIFO具有不同的名称和大小,并且如果要避免使用单独的显式代码来声明和初始化每个数据结构,则只有两种选择:写一个可重用的函数来完成此任务(这将需要执行动态分配,因此有义务向调用方释放代码),或编写类似函数的可重用宏。
宏解决方案似乎有点令人讨厌,是否有一些明显的方法可以简化我遗忘的操作?
使用动态宏似乎是实现动态分配的唯一途径。但是宏可以通过提供结构的初始化程序而不是一系列成员分配语句来针对更干净的代码。您可以在任何标准C版本中执行此操作,但是如果您可以依赖于C99中引入的指定初始化程序,那就更好了。
#define twi_make_fifo(name, size)\
twi_entry_t name##_data[1<<size];\
twi_fifo_t name = { .size_mask = ~(0xFFFF<<size), .data = name##_data };
请注意,我在那里依赖于这样一个事实:如果您为结构提供了初始化程序,那么所有未显式初始化的成员都将初始化为0 / NULL。还请注意,您当然也可以直接使用相同的表单,而无需宏。
如果可以为每个FIFO提供明确的代码,但是您只想避免手动编写每个集合,那么您可以编写自己的代码生成器来(重新)生成它们的代码,但是我我倾向于认为那可能是麻烦的多于其价值。