从另一个#define访问#define中的声明变量

时间:2013-09-04 23:12:56

标签: c

我有这段代码

struct counter_info {
    atomic_t counter;
    char *name;
} __attribute__((packed));

extern struct counter_info __start_counters;
extern struct counter_info __stop_counters;

#define __DOSOMETHING(F)                                    \
do{                                                         \
    static struct counter_info __counter_info_##F           \
    __attribute((__section__("counters")))                  \
    __attribute((__used__)) = {                             \
        .name = #F,                                         \
    };                                                      \
    atomic_set(&__counter_info_##F.counter, 0);             \
                                                            \
}while(0)

我将此宏称为:

__DOSOMETHING(FOO)

我想从其他代码访问__counter_info_##F

#define __DOSOMETHINGELSE(F)                                \
do{                                                         \
    atomic_inc(&__counter_info_##F.counter);            \
}while(0)

__DOSOMETHINGELSE(FOO)

但是我从编译器得到一个未声明的错误。这是为什么?可以吗?

编辑:

确切的错误是 error: ‘__counter_info_FOO’ undeclared (first use in this function) note: in expansion of macro ‘__DOSOMETHINGELSE’

2 个答案:

答案 0 :(得分:4)

你无法从另一段代码中获取该结构,因为你已经在一个支撑块内声明了它。 C范围规则禁止访问该块之外的代码。即使您让宏生成正确的名称,这也是正确的:__counter_info_F而不是__counter_info_FOO。

顺便说一句,这不是一个#define问题。当C看到代码时,所有宏处理都完成,编译器只看到预处理器生成的标记。

找到一种在没有宏的情况下完成工作的方法......然后找出一个宏表示来简化编码。

一种方法是使用不使用do循环来封闭这些变量的宏。现在的问题是生成唯一的名称。仔细查看这些宏,您会发现创建一次性循环以解决问题......创建双重定义的重复名称。如果打开宏生成的代码,则必须以另一种方式解决重复的名称问题......可能是通过添加宏参数。

有一件事,为了记录:你不需要像do或for包含普通块的复合语句。只是用括号括起来就足够了。你可以脱掉"做"在开头和"而(0);"最后,得到同样的效果。

答案 1 :(得分:0)

如果结构在函数中声明为static,则其可见性将仅限于该函数。示例(没有宏):

struct hoppa {
        int i;
        };

void start(void)
{
static struct hoppa one = {1};
}

void use_it(void)
{
one.i = 2; //FAIL
}