我遇到了一个奇怪的代码
static ROMCONST struct testcase * ROMCONST *patterns[] = {
patternbmk,
NULL
};
可以找到此代码here。
这是什么样的结构定义/声明?
有人可以用简单的英语解释什么意思吗?
答案 0 :(得分:3)
关于ROMCONST
:
就我们理解这些声明而言,ROMCONST
只是代替const
的一些噪声宏。
这种定义在嵌入式系统中很常见,在某些嵌入式系统中,有时需要非标准的东西才能在闪存中分配数据。哈佛架构尤其臭名昭著,但也可能需要使用非标准*far
指针的8/16位MCU。最后,如果该表分配在EEPROM /数据闪存中,尽管它是只读的,但仍可以在运行时进行更新,因此我们想添加volatile
。所有这些东西都可以隐藏在ROMCONST
内部。因此,理论上我们可能会遇到一些混乱和部分非标准的问题,例如
#define ROMCONST volatile const far PROGMEM
(volatile
来自eeprom /数据闪存,const
代表任何类型的闪存,far
代表存储的内存,PROGMEM
用于声明ROM上的数据)哈佛MCU。)
现在,我将忽略它,而将其替换为const
。
要了解其余代码的const
限定词,请从诸如patternbmk
之类的指向数组开始。
const struct testcase * const patternbmk[] = {
分开:
struct testcase * patternbmk[]
声明了一个指向结构的指针数组。const struct testcase * patternbmk[]
赋予那些指针只读访问权限。指向的数据为const
,无法通过这些指针进行修改。const struct testcase * const patternbmk[]
将指针本身设为只读,主要用于确保将表分配在闪存而不是RAM中。调整诸如*const
之类的编码样式,将指针声明及其限定符一起编写可能会有所帮助。
接下来,程序员希望声明一个指向这些指针数组的指针数组。 (如您所知,这开始变得混乱了……)可以使用两种方法来指向指针数组,方法是使用 array指针指向该数组或通过在数组的第一项(带有指针到指针)。程序员选择了后者。
数组项的类型为const struct testcase * const
,为了指向此类项,我们在右侧添加了一个附加的*
,最后是const struct testcase * const *
。从右到左读取这样的凌乱声明非常有帮助:指向const指针的指针到const struct测试用例。
然后他们希望创建一个由此类指针组成的数组,只需在末尾添加[]
:const struct testcase * const *patterns[]
。
并不是该数组中的每个初始化器都隐式地“衰减”为指向第一项的指针,所以初始化器patternbmk
会衰减为&patternmk[0]
,而该指针恰好是指向const指向const struct的指针测试用例,与我上面讨论的类型相同。
最后,static
限定词就在那里,将变量范围限制为声明它的文件。 patterns
初始化程序列表末尾的NULL是标记数组的末尾值。
答案 1 :(得分:2)
ROMCONST
最有可能是编译器指令,它可能是这样的:#define ROMCONST const
迫使变量进入代码存储区。
patterns
是数组的结构,存储另一个数组patternbmk
的结构,该结构包含具有testcase
结构定义的函数指针。
static ROMCONST struct testcase * ROMCONST *patterns[] = {
patternbmk,
NULL
};
ROMCONST struct testcase * ROMCONST patternbmk[] = {
#if !TEST_NO_BENCHMARKS
&testbmk1,
&testbmk2,
&testbmk3,
&testbmk4,
&testbmk5,
&testbmk6,
&testbmk7,
&testbmk8,
#if CH_USE_QUEUES
&testbmk9,
#endif
&testbmk10,
#if CH_USE_SEMAPHORES
&testbmk11,
#endif
#if CH_USE_MUTEXES
&testbmk12,
#endif
&testbmk13,
#endif
NULL
};
ROMCONST struct testcase testbmk1 = {
"Benchmark, messages #1",
NULL,
NULL,
bmk1_execute
};
struct testcase {
const char *name; /**< @brief Test case name. */
void (*setup)(void); /**< @brief Test case preparation function. */
void (*teardown)(void); /**< @brief Test case clean up function. */
void (*execute)(void); /**< @brief Test case execution function. */
};
答案 2 :(得分:0)
根据chibios标签,显示了一些google search
宏定义文档
#define ROMCONST const
ROM常数修饰符。
注意:
设置为在此端口中使用“ const”关键字。 在文件chtypes.h的第63行定义。