2

I read that the extern keyword is implicit in the context of functions, so unless you specify otherwise using the static keyword (which if I'm not mistaken is basically a completely separate concept from the static that variables employ—they just share a keyword), they are visible to all object files. This makes sense; having the declarations be implicitly external, while technically unnecessary when the declarations are in the same file as the definition, is useful because the programmer doesn't have to type extern every time they want to use a function out of its defining file, which is more often the case than not. What seems odd to me is that it is implicit for the declarations and the definition.

With a variable, I don't need to include an extern for the definition, and in fact, while I can do this without error, my compiler gives me a warning for it.

For example, I can have mylib.h:

int var = 5;

//it isn't necessary to write this as
//extern int var = 5;
//my compiler even warns against it

and test.c

#include "mylib.h"

extern int var;

I would normally assume the implicit extern for functions to be the same, that is, if I defined int func(int par) in mylib.h, there would not be an implicit extern before it, but there would be an implicit extern for any declaration of it (such as if I declared it for use in test.c).

It also doesn't make much sense from the perspective of the extern keyword being used as a way of telling the compiler to look elsewhere for the definition, when the definition would never be external of the file it is in.

I feel like I'm missing something here.

21
  • 3
    Maybe I misunderstand your question but it seems to me that you are doing this the wrong way. Putting int var into an h-file and putting extern int var in th c-file is not the usual way. Not sure these to Qs are dupes but I think you'll find the needed info by reading: stackoverflow.com/q/1433204/4386427 and stackoverflow.com/q/1410563/4386427 Commented Nov 11, 2020 at 7:12
  • 3
    If you write int var = 5; in mylib.h, then that defines the variable. In any given program, only one file can include mylib.h — if more than one file includes the header, you get multiply-defined errors. With GCC 10.x, by default, even if you write int var; in a header (rather than extern int var;), you will end up with multiple definition errors — though older versions of GCC did not do that by default. Commented Nov 11, 2020 at 7:13
  • 3
    For further discussion, see: How do I use extern to share variables between source files? and When to use extern “C” in C++? and When to use extern “C” in simple words? Commented Nov 11, 2020 at 7:18
  • 1
    The static keyword for both variables and functions limits the visibility of the named object. There are differences — you can have static variables inside functions, for example. But the concepts are sufficiently similar that saying "[static applied to functions] is basically a completely separate concept from the static that variables employ" is an overstatement at least. Commented Nov 11, 2020 at 7:19
  • 1
    @thepufferfish From the picture you linked it's obvious that the book is talking about two different source files (aka c-files). It's not talking about one h-file and one c-file. Commented Nov 11, 2020 at 7:28

1 Answer 1

3

If you use int x = 10; in any header file, then you are entering into trouble, because if you include the same header file in any other file (.c or .h) that is linked with test.c then you will get an error redefinition of variable x.

You can try that for yourself.

So always keep extern int x; in a header file, and define it int x = 10; in any .c file.

So, in this case, if you include the header file in multiple places, it is fine, because the header file only has a declaration and you can declare the same variable in multiple places without any problem.

you can try this sample program to test the error multiple definition of `global_value'

test.h

extern int global_value;

test.c

#include <stdio.h>
#include "test.h"
int global_value = 10;

int test_func()
{
        printf("golbal_value = %d", global_value);
        global_value = 20; // changed here, reflect in main after test_func call
}

main.c

#include <stdio.h>
#include "test.h"
int main()
{
        test_func();
        printf("global_value = %d\n", global_value);
        return 0;
}

the above program works perfectly. to get the error bring that extern int global_value; to test.c and int global_value = 10; to test.h and compile all together gcc test.c main.c

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this really helps me get a better understanding of why headers should not contain global variable definitions. So far as I understand, because headers are appended to the source file in preprocessing you basically could run into trouble with having multiple source files each defining that global variable, confusing the compiler. I guess you could theoretically have the same issue if you included the header twice in one source file, if you don't have inclusion guards; though I guess if your header doesn't have inclusion guards, that's a big problem to begin with.
So, I just thought of something. If there is the issue of global variables conflicting with themselves when defined in header files, does that mean that, given the implicit extern in functions, unless you define a function as static in a header, it would have the same issue? That is, it is better to declare the function in a header, but it is likely to cause issues if it is defined there?
generally we dont declare static functions in header files because we want to use the static functions in the one single .c not out side of the file. so we declare them in .c itself above all other statements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.