Question

main.h

extern int array[100];

main.c

#include "main.h"

int array[100] = {0};

int main(void)
{
    /* do_stuff_with_array */ 
}

In the main.c module, the array is defined, and declared. Does the act of also having the extern statement included in the module, cause any problems?

I have always visualized the extern statement as a command to the linker to "look elsewhere for the actual named entity. It's not in here.

What am I missing?

Thanks.

Evil.

Was it helpful?

Solution

The correct interpretation of extern is that you tell something to the compiler. You tell the compiler that, despite not being present right now, the variable declared will somehow be found by the linker (typically in another object (file)). The linker will then be the lucky guy to find everything and put it together, whether you had some extern declarations or not.

To avoid exposure of names (variables, functions, ..) outside of a specific object (file), you would have to use static.

OTHER TIPS

yea, it's harmless. In fact, I would say that this is a pretty standard way to do what you want.

As you know, it just means that any .c file that includes main.h will also be able to see array and access it.

Edit

In both C and C++, the presence of extern indicates that the first declaration is not a definition. Therefore, it just makes the name available in the current translation unit (anyone who includes the header) and indicates that the object referred to has external linkage - i.e. is available across all the translation units making up the program. It's not saying that the object is necessarily located in another translation unit - just that 'this line isn't the definition'.

End edit

In C, the extern is optional. Without it, the first declaration is a 'tentative definition'. If it were not for the later definition (which is unambiguously a definition because it has an initializer), this would be treated as a definition (C99 6.9.2). As it is, it's just a declaration and does not conflict.

In C++, the extern is not optional - without it, the first declaration is a definition (C++03 3.1) which conflicts with the second.

This difference is explicitly pointed out in Annex C of C++:

"Change: C++ does not have “tentative definitions” as in C

E.g., at file scope,

int i;
int i;

is valid in C, invalid in C++."

The extern is harmless and correct. You couldn't declare it in the header without extern.

As an extra, usually it is best practice to create a macro or a constant to hold the size of the array; in your code the actual size (100) appears twice in the source base. It would be cleaner to do it like this:

#define ARRAY_SIZE 100

extern int array[ARRAY_SIZE];

...

int array[ARRAY_SIZE] = { 0 };

But maybe you did not want to include this in the code snippet just for the sake of brevity, so please take no offense :)

From a compilation or execution point of view, it makes no difference.

However, it's potentially dangerous as it makes array[] available to any other file which #includes main.h, which could result in the contents of array[] being changed in another file.

So, if array[] will only ever be used in main.c, remove the line from main.h, and declare array[] as static in main.c.

If array[] will only be used in the main() function, declare it in there.

In other words, array[] should have its scope limited to the smallest possible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top