编译警告宏

1
2
3
4
/* compile time assertion */
#define RT_STATIC_ASSERT(name, expn) typedef char _static_assert_##name[(expn)?1:-1]

expn:判断条件;当条件不满足时;数组的长度初始化为-1,即编译报错;

用#waring 编译判断更为合理

宏过载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...)  _FUN

/**
* @ingroup msh
*
* This macro exports a command to module shell.
*
* @param command is the name of the command.
* @param desc is the description of the command, which will show in help list.
* @param opt This is an option, enter any content to enable option completion
*/
/* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */
#define MSH_CMD_EXPORT(...) \
__MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD2_OPT, \
_MSH_FUNCTION_CMD2)(__VA_ARGS__)
  • 这个宏 __MSH_GET_MACRO的作用是选择一个函数来调用。它接受五个参数:_1_2_3_FUN__VA_ARGS__,然后返回 _FUN

    __MSH_GET_MACRO被用来根据传入的参数数量来选择要调用的函数。具体来说,如果传入的参数数量为2,那么 _FUN就是 _MSH_FUNCTION_CMD2;如果传入的参数数量为3,那么 _FUN就是 _MSH_FUNCTION_CMD2_OPT

    这种技术被称为宏过载,它允许你根据传入的参数数量来选择不同的宏来执行。

    _FUN在这里的作用是作为一个占位符,它代表了要调用的函数。

宏定义

1
2
3
4
5
6
7
#define RTM_EXPORT(symbol)                                            \
const char __rtmsym_##symbol##_name[] rt_section(".rodata.name") = #symbol; \
const struct rt_module_symtab __rtmsym_##symbol rt_section("RTMSymTab")= \
{ \
(void *)&symbol, \
__rtmsym_##symbol##_name \
};
  1. __rtmsym_##symbol##_name:这是一个字符串常量,存储在 .rodata.name段中。
  2. __rtmsym_##symbol:这是一个 rt_module_symtab结构体的实例,存储在 RTMSymTab段中(.text)。它包含两个字段:
    • 一个是指向符号的指针。
    • 另一个是指向符号名称的指针。

这个宏定义的目的是为了在运行时能够通过符号的名称查找到符号的地址,实现动态链接和加载模块.

#undef

  • #undef 标识符,用来将前面定义的宏标识符取消定义。