C宏示例

时间:2015-10-19 07:05:53

标签: c macros

我遇到过这个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")))     = {     \

有人可以解释一下吗?感谢。

2 个答案:

答案 0 :(得分:5)

令牌##用于连接参数。

E.g。

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

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

这相当于说:

int a = MyFunction();

您可以在http://en.cppreference.com/w/c/preprocessor/replace了解更多详情。

答案 1 :(得分:1)

根据您发布的宏定义,调用

__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

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

宏观线

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

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

其他人已与##运营商的相关文档相关联;我不会偷他们。

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

该行

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

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

  

使用

     

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

     

部分(“section-name”)

     

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

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