Why declaring a variable in a .h file will allocate memory for each .c file includes it, Is it ANSI C?

StackOverflow https://stackoverflow.com/questions/17103297

  •  31-05-2022
  •  | 
  •  

Question

Assume I have a file.h and in it I have:

int arr[128];
(void)(*func_ptr)(int);

And I have code1.c, code2.c, code3.c includes it. Will arr and func_ptr will be global scope allocated for each .c file ? i.e. each .c file will have his own instance of arr and func_ptr? if so why is that ?

does using static can change the result ? what is the ANSI c rule?

Was it helpful?

Solution 2

Will arr and func_ptr will be global scope allocated for each .c file ?

Yes it will, and you will end up with a linking error since you have defined the same variable names several places at global scope.

Header files you #include in your .c files are just inserted into your .c file, there's nothing special about them. It works just as you concatenated all the header files your .c file includes, and then compile the result.

In that respect, the net result is exactly as if you wrote int arr[128]; in each of your .c file

OTHER TIPS

Declarations as these without initializing the variable explicitly are called "tentative definitions" in the C jargon. You can use these in multiple compilation units without problems. To be sure that there is at least one compilation unit where the symbol is effectively implemented you should have one real definition (including an initialization) in just one of the units, something like

int arr[128] = { 0 };
(void)(*func_ptr)(int) = 0;

Edit: The relevant part of the C standard is the following para from 6.9.2:

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

This will not compile because the variable arr is a global scope and you will get a linker error with a duplicate symbol.

If you declare it static, then it would be allocated in each sourcefile with a separate memory, but then it would be only accessible within that sourcefile or via pointer explicitly returned to a different file.

If you want to access the same block of memory in each sourcefile, you have to declare it in one file as above, and in all other files with extern prepended.

The same is for func_ptr

Update

If you add static to the definition, then the scope is local wherever you defined it. If you define a global static variable it will be visible only in that module. If you define a static variable in a function, it will be visible only in that function, so you can have the same name in multiple functions without interfering.

foo1()
{
     static int i;
}

foo2()
{
     static int i;
}

This would compile fine, because it acts similar like a namespace.

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