在 C 中设置静态分配结构的宏
Macro to set up statically allocated struct in C
我有以下 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;
宏解决方案似乎有点令人反感,是否有一些明显的方法可以简化我忘记的操作?
如果您的 FIFO 具有不同的名称和大小,并且如果您想避免为每个 FIFO 的数据结构声明和初始化使用单独的显式代码,那么只有两种选择:编写一个可重用的函数来执行作业(需要执行动态分配,因此调用者有义务释放),或者编写可重用的 function-like 宏。
The macro solution seems a bit distasteful, is there some obvious way of simplifying this operation that I'm forgetting about?
如果 table 关闭动态分配,使用宏来实现您的目的似乎是实现它的唯一方法。但是宏可以通过为结构提供初始化程序而不是一系列 member-assignment 语句来针对更清晰的代码。您可以在任何版本的标准 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 都有明确的代码是可以的,但您只是想避免手动编写每个集合,那么您可以自己编写一个代码生成器来(重新)为它们生成代码,但是我倾向于认为这可能比它的价值更麻烦。
我有以下 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;
宏解决方案似乎有点令人反感,是否有一些明显的方法可以简化我忘记的操作?
如果您的 FIFO 具有不同的名称和大小,并且如果您想避免为每个 FIFO 的数据结构声明和初始化使用单独的显式代码,那么只有两种选择:编写一个可重用的函数来执行作业(需要执行动态分配,因此调用者有义务释放),或者编写可重用的 function-like 宏。
The macro solution seems a bit distasteful, is there some obvious way of simplifying this operation that I'm forgetting about?
如果 table 关闭动态分配,使用宏来实现您的目的似乎是实现它的唯一方法。但是宏可以通过为结构提供初始化程序而不是一系列 member-assignment 语句来针对更清晰的代码。您可以在任何版本的标准 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 都有明确的代码是可以的,但您只是想避免手动编写每个集合,那么您可以自己编写一个代码生成器来(重新)为它们生成代码,但是我倾向于认为这可能比它的价值更麻烦。