Take the 2-minute tour ×

I'm having some trouble with some struct typedef declarations in a header file not seeming to go through to my implementation file.

Specifically, I have the following types defined: Type, Value, Integer, String, and Float. They are all typedef'd from struct names, in the exact same manner. I'm writing an informal hashCode function to supplement a hashtable I'm designing that references all of these data types. Type and Value work okay, but Integer/Float/String do not work properly and I can't figure out why.

I apologize, this question is a little involved, but I'll try not to provide too much or too little information and maybe this won't be too difficult for the experts here. :-)

I'll start with the hashCode function (and please don't give me flak about how crappy it is, I know it's not all that great and I really don't care):

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;

                        return -1;

Excerpt from the "type.h" header file, which defines all of the types. It's worth noting that I've also tried having the typedef and the struct definition combined as one statement, but that didn't work either:

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;

When I run make, I get the following:

[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

As I mentioned, Type * and Value * are valid data types, but the other three aren't. The whichType and type functions do not use any of the other three data types.

Thanks in advance for any help. I'm fairly sure this has to do either with the location of the structs within the header file, or possibly (but highly unlikely) gcc itself.

share|improve this question
Not an answer to your question, but I'm pretty sure you're going to want to insert 'break's at the end of your case blocks. –  theycallmemorty Oct 9 '09 at 1:59
You have #included your header, right? –  Nick Bedford Oct 9 '09 at 2:00
theycallmemorty: It looks like he's finishing each one with a return, so break isn't necessary. –  caf Oct 9 '09 at 2:01
caf: not the FLOAT case. :) –  theycallmemorty Oct 9 '09 at 2:02
The FLOAT case was mis-copied, sorry. I'm copying from a shell window, instead of a GUI text editor like I should. -_- It's missing a few lines. @Nick Bedford: Yeah, that's a mistake too elementary even for me. –  Platinum Azure Oct 9 '09 at 2:05

2 Answers 2

up vote 2 down vote accepted

In C you can only declare a variable at the start of a block. Your line:


tries to declare a variable i, but it is not at the start of a block. You can fix this just by opening a block:

    return i->value % hash->capacity;

...and similar for the other cases.

share|improve this answer
Really? I've never had trouble with this before... Consider the "for" loop in the "case STRING" portion-- that declaration isn't at the beginning of a block either. But I'll definitely try and see what happens. –  Platinum Azure Oct 9 '09 at 2:04
Well, I'll be. That was it. Thanks very much. +1 and check mark for you. –  Platinum Azure Oct 9 '09 at 2:06
You are talking about C89 -- in C99, you can define variables anywhere in a code block, just as you can in C++. –  Jonathan Leffler Oct 9 '09 at 2:53

You can't declare a variable inside a case block.

That's not entirely true actually. See here. Should help you clear things up.

share|improve this answer
Very informative. I never knew that-- that is so weird. I really wish gcc would have made that point clear, but I've learned long ago that gcc is hardly ever verbose even if it is always correct. Thanks for the reply. –  Platinum Azure Oct 9 '09 at 2:08
There's nothing weird about it if you think about case as what it really is. It's not a block, it's just a label, for which switch is a computed goto. That's why a case can be located inside a while loop, for example, so long as that while loop is within switch (and hence we get to Duff's device). –  Pavel Minaev Oct 9 '09 at 3:50

Your Answer


