1

I would like to make a linked list globally available across multiple .c files.

I've read how to do this but I can't identify what is causing my problem.

I declare the variable with extern in LinkedList.h:

extern LinkedList* canQueue;

And then in main.c I initialise the variable by sending it to a function in LinkedList.c like so:

LinkedList *canQueue=createList();

This is the create function in LinkedList.c:

LinkedList* createList() /*creates empty linked list*/
  {
    LinkedList* myList;
    myList = malloc(sizeof(LinkedList));
    myList->head = NULL;
    return myList;
  }

I then want to use the canQueue in another file, cpu.c. I've included LinkedList.h in the cpu.c, so at this point the Linked List should be available here from what I know. But when I try to access it I get an error:

undefined reference to 'canQueue'

Have I missed something or done something wrong?

Dawson
  • 573
  • 6
  • 24

2 Answers2

2

It seems that you simply don't define such a global variable. If this code compiles:

LinkedList *canQueue = createList();

then it's not a "global" (file-scope) variable. Define it at file scope and initialize it carefully so you don't shadow it with a local variable. All in all, do something like this:

// at global scope
LinkedList *canQueue;

void initialize() // or whatever
{
    canQueue = createList();
}
  • Good point. Now that I've changed it to `LinkedList *cpuQueue `, I still get the undefined reference errors so I've done something wrong with the declaration. – Dawson May 03 '13 at 07:39
  • @Dawson Definitely. Make sure it isn't `static`, it's *actually* declared as `extern` in the header, etc. –  May 03 '13 at 07:40
  • @Dawson "Now that I've changed it to LinkedList *cpuQueue" .. it's a different name ... where did you change it? in .h or .c? – Ferenc Deak May 03 '13 at 07:48
  • sorry I mean canQueue, I changed the declaration in main.c – Dawson May 03 '13 at 07:50
  • @H2CO3 Can you tell me something plain and simple.What storage class variables declared at file scope have? **extern** or **static**.I read in many places that global variables have **extern** storage class by default,but a 80k reputation user on SO tells me they have default **static** storage. – Rüppell's Vulture May 03 '13 at 07:50
  • @H2CO3 I think I got the exact answer. http://stackoverflow.com/questions/3281925/what-is-default-storage-class-for-global-variables – Rüppell's Vulture May 03 '13 at 07:53
  • @Rüppell'sVulture `extern`, unless declared as `static`. –  May 03 '13 at 08:08
  • @H2CO3 `LinkedList *canQueue = createList();` will this line compile? file scope variables should have constant expression as initializers right? – Koushik Shetty May 03 '13 at 08:59
  • @Koushik Apparently that line was at function scope -- read the second sentence in my answer. –  May 03 '13 at 09:00
1

You need to assign a constant to a global variable when initializing it.And return of a function is not considered a constant.So the following will show error:

 LinkedList *canQueue=createList();

Edit I missed it that you have declared and initialized the pointer *canQueue at function scope instead of file scope.That goes against the very definition of a global variable.But there's one more catch.If you declare something like LinkedList *canQueue=createList(); at the file-scope, you'll get the following error:

     Initializer element not constant

Since the object will be "declared" at file scope, it has static storage duration. Initializers for objects of static storage duration must be constant expressions. The result of a function call is not a constant expression

Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49