【问题标题】:C macro exampleC 宏示例
【发布时间】:2015-10-19 07:05:52
【问题描述】:

我遇到了这个 C 宏:

    #define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel)\
    static struct cmd                       \
    __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
    __attribute__((used)) __attribute__((section("__cmd"))) = { \
        .name = (_name),                    \
        .args = (_args),                    \
        .cmd = (_nlcmd),                    \
        .nl_msg_flags = (_flags),               \
        .hidden = (_hidden),                    \
        .idby = (_idby),                    \
        .handler = (_handler),                  \
        .help = (_help),                    \
        .parent = _section,                 \
        .selector = (_sel),                 \
    }

我隐约明白它试图从宏的一堆输入参数中定义一个cmd 类型的结构。但我真的不明白这两行是什么意思:

 __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
 __attribute__((used)) __attribute__((section("__cmd")))     = {     \

谁能解释一下?谢谢。

【问题讨论】:

标签: c macros


【解决方案1】:

标记## 用于连接参数。

例如

#define CONCAT(A, B) A ## B

int a = CONCAT(My, Function)();

这相当于说:

int a = MyFunction();

您可以在http://en.cppreference.com/w/c/preprocessor/replace查看更多详细信息。

【讨论】:

    【解决方案2】:

    鉴于您发布的宏定义,调用

    __COMMAND( Section, Symname, Name, Args, Nlccmd, Flags, Hidden, Idby, Handler, Help, Sel );
    

    将解析为:

    static struct cmd
    __cmd_Symname_Handler_Nlcmd_Idby_Hidden
    __attribute__((used)) __attribute__((section("__cmd"))) = {
        .name = (Name),
        .args = (Args),
        .cmd = (Nlcmd),
        .nl_msg_flags = (Flags),
        .hidden = (Hidden),
        .idby = (Idby),
        .handler = (Handler),
        .help = (Help),
        .parent = (Section),
        .selector = (Sel ),
    };
    

    线

    static struct cmd
    

    开始定义struct cmd 类型的static 对象(在别处声明)。

    宏线

    __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
    

    使用宏的参数来连接struct cmd 的标识符(显然希望它是唯一的)。

    其他人已经链接到##运营商的相关文档;我不会从他们那里偷东西。

    此时需要注意的是,以__ 开头的标识符是为(编译器和标准库的)实现保留的,所以严格来说这会使程序不符合语言标准。 (这并不重要,因为下面使用__attribute__ 无论如何都是不可移植的。)

    线

    __attribute__((used)) __attribute__((section("__cmd"))) = { \
    

    设置结构的"attributes" 。这是特定于编译器的语法扩展。来自 GCC 文档:

    二手

    此属性附加到具有静态存储的变量,意味着即使看起来未引用该变量,也必须发出该变量。

    节(“节名”)

    通常,编译器会将其生成的对象放在数据和 bss 等部分中。但是,有时您需要额外的部分,或者您需要某些特定变量出现在特殊部分中,例如映射到特殊硬件。 section 属性指定变量(或函数)位于特定的部分中。 [...]

    然后它继续使用传递给宏的参数初始化结构成员。

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多