2

I cannot for the life of me figure why my code isn't compiling. I am using an up to date gcc version to compile and this code is in the bottom part of a lex file (so it is copied directly into a .c file after using flex on it) which makes me 90% sure that this problem is due to something I am doing wrong in C. Here is the code which is causing problems:

void checkAliases() {
    if (aliasHead==0) {
        printf("No aliases have been created.");
    }
    else {
    struct AliasNode* current = aliasHead;
    printf("Current Aliases: \n");
    while (current!=0) {
        printAlias(current);
        current = current->next;
    }
}

struct AliasNode {
    struct AliasNode* next;
    char* key;
    char* value;
};

struct AliasNode* aliasHead = 0;


void printAlias(struct AliasNode* alias) {
    char* toPrint = alias->key;
    printf(toPrint);
    printf(": ");
    toPrint = alias->value;
    printf(toPrint);
    printf("\n");
}

Here are the errors I am getting:

error: ‘aliasHead’ undeclared (first use in this function)
   if (aliasHead==0) {
       ^
error: unknown type name ‘AliasNode’
   AliasNode* current = aliasHead;

error: request for member ‘next’ in something not a structure or union
    current = current->next;
                     ^

error: unknown type name ‘AliasNode’
   AliasNode* next;
   ^

This C code (along with thousands of lines more that I left out) is generated by this yacc file:

%token CD BYE ALIAS

%%

program: /*empty*/
     | program command
    ;

command:
    cd|bye|alias

cd:     
    CD     {printf("Not a valid directory\n");    }
    ;
bye:    
    BYE    {exit(0); }
     ;
alias:
    ALIAS   {
    if (aliasHead==0) {
        printf("No aliases have been created.");
    }
    else {
    AliasNode* current = aliasHead;
    printf("Current Aliases: \n");
    while (current!=0) {
        printAlias(current);
        current = current->next;
    }


    }
    }
    ;

    %%

    /*global variables*/

/*linked list to store alias - command pairs */
struct AliasNode {
    AliasNode* next;
    char* key;
    char* value;
};

struct AliasNode* aliasHead = 0;

void printAlias(struct AliasNode* alias) {
    char* toPrint = alias->key;
    printf(toPrint);
    printf(": ");
    toPrint = alias->value;
    printf(toPrint);
    printf("\n");
}

I am absolutely lost as to how to fix these errors. Any help at all, even if its just a nudge in the right direction, is greatly appreciated. Thanks in advance!

Edit:

I changed my code in the Yacc file so that now when I put it through Bison, the .c I get out has this:

struct AliasNode {
AliasNode* next;
char* key;
char* value;
};

struct AliasNode* aliasHead = 0;

void printAlias(struct AliasNode* alias) {
    char* toPrint = alias->key;
    printf(toPrint);
    printf(": ");
    toPrint = alias->value;
    printf(toPrint);
    printf("\n");
}

void aliasNoPrompt() {
    if (aliasHead==0) {
        printf("No aliases have been created.");
    }
    else {
        AliasNode* current = aliasHead;
        printf("Current Aliases: \n");
        while (current!=0) {
            printAlias(current);
            current = current->next;
    }
}

However, I am still running into the same errors noted above. Note that from the main, I call aliasNoPrompt().

Code
  • 151
  • 1
  • 1
  • 9
  • 5
    If the code is actually in that order, then you are using `aliasHead` above where it is declared (things must be declared or defined before use). – crashmstr Mar 27 '15 at 17:53
  • 2
    You can legitimately declare a `struct AliasNode *` before defining the contents of the structure, but you can't access any of the elements within the structure before you've defined the contents of the structure (and you couldn't define a `struct AliasNode` variable - only the pointer is OK). Thus, the declaration of `current` isn't a problem, but the reference to `current->next` is. – Jonathan Leffler Mar 27 '15 at 18:03
  • 1
    See also: [Does the C Standard consider that there are one or two `struct uperms_entry` types in this header?](http://stackoverflow.com/questions/11697705) and [Am I correct to assume one cannot forward declare a library's opaque pointer type?](http://stackoverflow.com/questions/27912385/) – Jonathan Leffler Mar 27 '15 at 18:09

2 Answers2

3

Put the declaration to the top of your code. C requires code written in top to down order, meaning you should define AliasNode before use it.

struct AliasNode {
    struct AliasNode* next;
    char* key;
    char* value;
};

struct AliasNode* aliasHead = 0;

// ... other code here
Wayne
  • 641
  • 6
  • 11
  • Note though, the code posted in the question wouldn't compile with C99. – maelswarm Mar 27 '15 at 18:01
  • 1
    Are you saying that C99 doesn't need variables to be declared before you use them? Because I'm pretty sure it does. – sepp2k Mar 27 '15 at 18:49
  • I tried to change my code (as detailed in the edit of my original post) to match this, but I still get the same errors. Do you think it might be a problem with my compiler? – Code Mar 27 '15 at 22:05
  • @sepp2k not what I'm saying at all – maelswarm Mar 27 '15 at 22:20
  • @Roecrew When I said "you", I meant Wayne, not you. Specifically I was referring to "C **(before C99)** requires code written in top to down order", which certainly sounds like he's saying that this changed with C99. – sepp2k Mar 27 '15 at 22:25
2

Your struct declaration has to be above functions that use it.


struct AliasNode {
    struct AliasNode* next;
    char* key;
    char* value;
};

struct AliasNode* aliasHead = 0;

void printAlias(struct AliasNode* alias) {
    char* toPrint = alias->key;
    printf(toPrint);
    printf(": ");
    toPrint = alias->value;
    printf(toPrint);
    printf("\n");
}

void checkAliases() {
if (aliasHead==0) {
        printf("No aliases have been created.");
    }
    else {
    struct AliasNode* current = aliasHead;
    printf("Current Aliases: \n");
    while (current!=0) {
        printAlias(current);
        current = current->next;
    }
}
maelswarm
  • 1,163
  • 4
  • 18
  • 37
  • Why do you have "struct AliasNode* aliasHead = 0;" ? Is your main()in this file? If so, move the struct declaration above the main. – maelswarm Mar 27 '15 at 17:57
  • My main is in my lex.yy.c file which is generated by flex from my .l file. I changed the order of statements as described above and get the same errors. – Code Mar 27 '15 at 22:09