结构定义

Struct definition

我已经运行进入了一个奇怪的代码

static ROMCONST struct testcase * ROMCONST *patterns[] = {
  patternbmk,
  NULL
};

可以找到此代码 here

这是什么结构definition/declaration?

谁能用通俗易懂的英语解释一下这是什么意思?

根据 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 是标记值,标记数组的结尾。