结构定义
Struct definition
我已经运行进入了一个奇怪的代码
static ROMCONST struct testcase * ROMCONST *patterns[] = {
patternbmk,
NULL
};
可以找到此代码 here。
这是什么结构definition/declaration?
谁能用通俗易懂的英语解释一下这是什么意思?
根据chibios tag, some google search显示
Macro Definition Documentation
#define ROMCONST const
ROM constant modifier.
Note:
It is set to use the "const" keyword in this port.
Definition at line 63 of file chtypes.h.
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. */
};
关于ROMCONST
:
就我们理解这些声明而言,ROMCONST
只是用来代替 const
的噪声宏。
此类定义在嵌入式系统中很常见,您有时需要非标准的东西才能在闪存中分配数据。尤其是哈佛架构为此臭名昭著,但 8/16 位 MCU 可能需要非标准 *far
指针。最后,如果 table 分配在 EEPROM/data 闪存中,尽管它是只读的,但它可以在 运行 时间内更新,所以我们想添加 volatile
.所有这些东西都可以隐藏在 ROMCONST
中。所以理论上我们可以有一些混乱和部分不标准的东西,比如
#define ROMCONST volatile const far PROGMEM
(其中 volatile
来自 eeprom/data flash,const
用于任何类型的 flash,far
用于 banked 内存,PROGMEM
用于声明的东西哈佛 MCU 上的 ROM 中的数据。)
现在,我将忽略它并将其替换为 const
。
要理解其余代码的 const
限定符,请从指向数组开始,例如 patternbmk
.
const struct testcase * const patternbmk[] = {
拆开这个:
struct testcase * patternbmk[]
声明一个指向结构的指针数组。
const struct testcase * patternbmk[]
为这些指针提供只读访问权限。指向的数据是const
,不能通过这些指针修改。
const struct testcase * const patternbmk[]
使指针本身为只读,主要用于确保 table 分配在闪存而不是 RAM 中。
采用 *const
等编码风格可能会有所帮助,将指针声明及其限定符写在一起。
接下来,程序员希望声明一个指向这些指针数组的指针数组。 (你可以看出这开始变得混乱......)有两种方法可以用来指向指针数组,或者通过使用 array pointer 指向数组或者通过指向指针的指针指向数组的第一项。程序员选择了后者。
数组项的类型为 const struct testcase * const
,为了指向这样的一项,我们在右侧添加了一个额外的 *
,以 const struct testcase * const *
结尾。从右到左阅读这样的混乱声明很有帮助:指向 const 的指针-指向 const struct 测试用例的指针。
然后他们希望制作一个这样的指针到指针的数组,只需在末尾添加一个[]
:const struct testcase * const *patterns[]
.
并不是这个数组中的每个初始化器都隐式地 "decays" 指向第一项的指针,所以初始化器 patternbmk
衰减到 &patternmk[0]
恰好是指向 const- 的指针指向 const struct 测试用例的指针,与我上面讨论的类型相同。
最后 static
限定符只是为了将变量范围限制在声明它的文件中。 patterns
初始化列表末尾的 NULL 是标记值,标记数组的结尾。
我已经运行进入了一个奇怪的代码
static ROMCONST struct testcase * ROMCONST *patterns[] = {
patternbmk,
NULL
};
可以找到此代码 here。
这是什么结构definition/declaration?
谁能用通俗易懂的英语解释一下这是什么意思?
根据chibios tag, some google search显示
Macro Definition Documentation
#define ROMCONST const
ROM constant modifier.
Note:
It is set to use the "const" keyword in this port. Definition at line 63 of file chtypes.h.
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. */
};
关于ROMCONST
:
就我们理解这些声明而言,ROMCONST
只是用来代替 const
的噪声宏。
此类定义在嵌入式系统中很常见,您有时需要非标准的东西才能在闪存中分配数据。尤其是哈佛架构为此臭名昭著,但 8/16 位 MCU 可能需要非标准 *far
指针。最后,如果 table 分配在 EEPROM/data 闪存中,尽管它是只读的,但它可以在 运行 时间内更新,所以我们想添加 volatile
.所有这些东西都可以隐藏在 ROMCONST
中。所以理论上我们可以有一些混乱和部分不标准的东西,比如
#define ROMCONST volatile const far PROGMEM
(其中 volatile
来自 eeprom/data flash,const
用于任何类型的 flash,far
用于 banked 内存,PROGMEM
用于声明的东西哈佛 MCU 上的 ROM 中的数据。)
现在,我将忽略它并将其替换为 const
。
要理解其余代码的 const
限定符,请从指向数组开始,例如 patternbmk
.
const struct testcase * const patternbmk[] = {
拆开这个:
struct testcase * patternbmk[]
声明一个指向结构的指针数组。const struct testcase * patternbmk[]
为这些指针提供只读访问权限。指向的数据是const
,不能通过这些指针修改。const struct testcase * const patternbmk[]
使指针本身为只读,主要用于确保 table 分配在闪存而不是 RAM 中。
采用 *const
等编码风格可能会有所帮助,将指针声明及其限定符写在一起。
接下来,程序员希望声明一个指向这些指针数组的指针数组。 (你可以看出这开始变得混乱......)有两种方法可以用来指向指针数组,或者通过使用 array pointer 指向数组或者通过指向指针的指针指向数组的第一项。程序员选择了后者。
数组项的类型为 const struct testcase * const
,为了指向这样的一项,我们在右侧添加了一个额外的 *
,以 const struct testcase * const *
结尾。从右到左阅读这样的混乱声明很有帮助:指向 const 的指针-指向 const struct 测试用例的指针。
然后他们希望制作一个这样的指针到指针的数组,只需在末尾添加一个[]
:const struct testcase * const *patterns[]
.
并不是这个数组中的每个初始化器都隐式地 "decays" 指向第一项的指针,所以初始化器 patternbmk
衰减到 &patternmk[0]
恰好是指向 const- 的指针指向 const struct 测试用例的指针,与我上面讨论的类型相同。
最后 static
限定符只是为了将变量范围限制在声明它的文件中。 patterns
初始化列表末尾的 NULL 是标记值,标记数组的结尾。