宏中结构的问题定义

时间:2011-03-22 21:40:12

标签: c macros struct types function-pointers

我正在研究C中的宏,尝试模拟objet行为但是使用C并且我对从宏中另一个结构中的结构定义的变量的定义有疑问。那是我的代码......它有效:

#include <stdio.h>
#include <stdlib.h>

#define STACK_MAX_CAPACITY 10
#define DECLARE_STACK(Type)                             \
    typedef struct MetaPile_##Type;                     \
                                                        \
    typedef struct Pile_##Type_t{                       \
        Type q[STACK_MAX_CAPACITY];                     \
        int pos;                                        \
    } Pile_##Type;                                      \
                                                        \
    typedef struct MetaPile_##Type_t{                   \
        void (* push) ( Pile_##Type* p, Type val );     \
        void (*init) (Pile_##Type* p);                  \
    } MetaPile_##Type;                                  \
                                                        \
    void init_##Type( Pile_##Type* p ){                 \
        p->pos = 0;                                     \
        int i;                                          \
        for(i=0; i<STACK_MAX_CAPACITY; i++){            \
            p->q[i]=0;                                  \
        }                                               \
    }                                                   \
                                                        \
    void push_##Type( Pile_##Type* p, Type val ) {      \
        if(p->pos < STACK_MAX_CAPACITY){                \
            p->q[p->pos]=val;                           \
            p->pos++;                                   \
        }                                               \
    }                                                   \
    MetaPile_##Type TheMetaPile_##Type;                 \
    void initTheMetaPile_##Type(){                      \
        TheMetaPile_##Type.init = &init_##Type;         \
        TheMetaPile_##Type.push = &push_##Type;         \
    }                                                   \
                                                        \

DECLARE_STACK(int)

int main(){

    int i;

    initTheMetaPile_int();
    Pile_int pi;

    TheMetaPile_int.init(&pi);

    push_int(&pi, 2);
    push_int(&pi, 3);
    push_int(&pi, 4);
    push_int(&pi, 5);
    push_int(&pi, 6);

    for(i=0; i<STACK_MAX_CAPACITY; i++){
        printf("%d",pi.q[i]);
    }

    return 0;
}

第一个结构定义了一个dinamic类型的数组,这要归功于代表objet的attributs方面的宏(Pile _ ## Type),以及另一个将管理“方法”的结构(MetaPile _ ## Type)。 objet,通过功能指针。 fonction init用作构造函数并初始化我的“objet”pi。

现在我想要的是在桩_ ##中引用类型MetaPile类型的变量_ ## Type(调用例如myClass)以便能够进行pi-&gt; myClass-&gt;推送和调用功能push_int。但是当我做的时候:

typedef struct Pile_##Type_t{                       \
    Type q[STACK_MAX_CAPACITY];                     \
    int pos;                                        \
    MetaPile_##Type myClass;                        \
} Pile_##Type;                                      \

我有一个误解的错误......

D:\main.c|40|warning: useless keyword or type name in empty declaration|
D:\main.c|40|error: syntax error before "MetaPile_int"|
D:\main.c|40|warning: no semicolon at end of struct or union|
D:\main.c|40|warning: type defaults to `int' in declaration of `Pile_int'|
D:\main.c|40|warning: data definition has no type or storage class|
D:\main.c|40|error: syntax error before '*' token|
D:\main.c|40|error: syntax error before '*' token|
D:\main.c|40|error: syntax error before '*' token|
D:\main.c||In function `init_int':|
D:\main.c|40|error: `p' undeclared (first use in this function)|
D:\main.c|40|error: (Each undeclared identifier is reported only once|
D:\main.c|40|error: for each function it appears in.)|
D:\main.c|40|error: syntax error before '*' token|
D:\main.c||In function `push_int':|
D:\main.c|40|error: `p' undeclared (first use in this function)|
D:\main.c|40|error: `val' undeclared (first use in this function)|
D:\main.c||In function `main':|
D:\main.c|47|error: syntax error before "pi"|
D:\main.c|49|error: `pi' undeclared (first use in this function)|
||=== Build finished: 12 errors, 4 warnings ===|

我不知道myClass的定义是什么,我也使用了*但错误仍然存​​在。谢谢,如果有人可以提供帮助。

3 个答案:

答案 0 :(得分:4)

你的问题不是宏的使用,这只会分散你的注意力。

typedef struct MetaPile_int;

在语法上是不正确的。 struct的简单前向声明如下:

struct MetaPile_int;

但如果你只是想让自己的生活更轻松,那么就这样做:

typedef struct MetaPile_int MetaPile_int;

这是struct的前向声明以及标识符MetaPile_int的定义。

要使其正常工作,请先尝试将其放入宏中。或者使用可帮助您跟踪宏中的错误的编译器,例如clang。

答案 1 :(得分:2)

删除typedef struct MetaPile_##Type;行 - 应该做什么(除了导致错误之外),

答案 2 :(得分:0)

您尝试在声明之前插入完整的结构(MetaPile_##Type),更改它们的顺序[在MetaPile_##Type中您只使用指向Pile_##Type_t的指针,以及指针已知]: 编辑: 这个声明对我很有用:

#define DECLARE_STACK(Type)                             \
    struct Pile_##Type_t;                     \
                                                        \
    typedef struct MetaPile_##Type_t{                   \
        void (* push) ( Pile_##Type_t* p, Type val );     \
        void (*init) (Pile_##Type_t* p);                  \
    } MetaPile_##Type;                                  \
                                                        \
    typedef struct Pile_##Type_t{                       \
        Type q[STACK_MAX_CAPACITY];                     \
        int pos;                                        \
    MetaPile_##Type myClass;                        \
    } Pile_##Type;                                      \
                                                        \
    void init_##Type( Pile_##Type* p ){                 \
        p->pos = 0;                                     \
        int i;                                          \
        for(i=0; i<STACK_MAX_CAPACITY; i++){            \
            p->q[i]=0;                                  \
        }                                               \
    }                                                   \
                                                        \
    void push_##Type( Pile_##Type* p, Type val ) {      \
        if(p->pos < STACK_MAX_CAPACITY){                \
            p->q[p->pos]=val;                           \
            p->pos++;                                   \
        }                                               \
    }                                                   \
    MetaPile_##Type TheMetaPile_##Type;                 \
    void initTheMetaPile_##Type(){                      \
        TheMetaPile_##Type.init = &init_##Type;         \
        TheMetaPile_##Type.push = &push_##Type;         \
    }                                                   \
                                                        \

它应该做的工作。