typedefs структур, которые, кажется, не проходят через заголовочные файлы? - PullRequest
0 голосов
/ 09 октября 2009

У меня возникли проблемы с некоторыми объявлениями struct typedef в заголовочном файле, которые, похоже, не проходят через мой файл реализации.

В частности, у меня определены следующие типы: Type, Value, Integer, Stringи плавать.Все они typedef'd из структурных имен, точно так же.Я пишу неофициальную функцию hashCode в дополнение к разрабатываемой хэш-таблице, которая ссылается на все эти типы данных.Тип и значение работают хорошо, но Integer / Float / String не работают должным образом, и я не могу понять, почему.

Я извиняюсь, этот вопрос немного сложен, но я постараюсь не предоставлять слишкоммного или слишком мало информации, и, возможно, это не будет слишком сложным для экспертов здесь.: -)

Я начну с функции hashCode (и, пожалуйста, не беспокойтесь о том, насколько она дрянная, я знаю, что это не так уж и здорово, и мне все равно):

int hashCode(ST_HashSymbol *hash, Value *v)
{
        Type *t = v->type;

        switch (whichType(t->name))
        {
                case INTEGER:
                        Integer *i = (Integer *)v->innerValue;
                        return i->value % hash->capacity;

        case FLOAT:
        {
            Float *f = (Float *)v->innerValue;
            float val = f->value;
            long l = 0l;

            if (val  2 && j = 0; --j)
            {
                if (val >= pow(2, j - 22))
                {
                    val -= pow(2, j - 22);
                    l |= 1 capacity;
        }

                case STRING:
                        String *s = (String *)v->innerValue;
                        char *str = s->value;

                        int total = 0;

                        char *c;
                        for (c = str; *c != '\0'; ++c)
                        {
                                total += *c;
                        }

                        return total % hash->capacity;

                default:
                        return -1;
        }
}

Выдержка из заголовочного файла "type.h", который определяет все типы.Стоит отметить, что я также пытался объединить определение типа и определение структуры в одно выражение, но это тоже не сработало:

typedef struct _t Type;
typedef struct _v Value;

struct _t {
        char *name;
        struct _t *widerType;
};

struct _v {
        Type *type;
        void *innerValue;
};

Type *type(int);
int whichType(char *);
Type *getType(char *);

/**************************/
/* Actual ("inner") types */
/**************************/

typedef struct _str String;
typedef struct _int Integer;
typedef struct _fl Float;

struct _str {
        int length;
        char *value;
};

struct _int {
        int value;
};
struct _fl {
        float value;
};

Когда я запускаю make, я получаю следующее:

[kparting@dhcp-10-25-247-130 eq]$ make
gcc -o eq -Wall -g parser.c eq.c error.c hash.c symbols.c type.c -lm
hash.c: In function ‘hashCode’:
hash.c:33: error: expected expression before ‘Integer’
hash.c:34: error: ‘i’ undeclared (first use in this function)
hash.c:34: error: (Each undeclared identifier is reported only once
hash.c:34: error: for each function it appears in.)
hash.c:37: error: expected expression before ‘Float’
hash.c:38: error: ‘f’ undeclared (first use in this function)
hash.c:69: error: expected expression before ‘String’
hash.c:70: error: ‘s’ undeclared (first use in this function)
make: *** [eq] Error 1

Как я уже говорил, Тип * и Значение * являются допустимыми типами данных, но остальные три - нет.Функции whichType и type не используют другие три типа данных.

Заранее благодарим за любую помощь.Я вполне уверен, что это связано либо с расположением структур в заголовочном файле, либо, возможно, (но крайне маловероятно) с самим gcc.

Ответы [ 2 ]

4 голосов
/ 09 октября 2009

Вы не можете объявить переменную внутри блока case.

Это не полностью правда на самом деле. См. Здесь. Должно помочь вам прояснить ситуацию.

2 голосов
/ 09 октября 2009

В C вы можете объявить переменную только в начале блока. Ваша линия:

Integer *i = (Integer *)v->innerValue;

пытается объявить переменную i, но она не в начале блока. Вы можете исправить это, просто открыв блок:

case INTEGER:
{
    Integer *i = (Integer *)v->innerValue;
    return i->value % hash->capacity;
}

... и аналогичные для других case с.

...