Global variables defined in source and header file

duragezic

Lifer
Oct 11, 1999
11,234
4
81
I have seen instances where global variables are seemingly doubly defined, but not? i.e.

/* myFile.h */
int myInt;

/* myFile.c */
#include <myFile.h>
int myInt;


I would've expected an error because that is doubly defining a variable, no? But apparently this works. I'd like to see the definition only once in the source file, and declarations (extern) done in header files as needed. I believe with functions, that the prototype is a declaration (extern) by default so using extern with a function does not do anything. But in this case it is global variables.

So I don't think the above is good practice but I'm curious how it even works.

Also, when you use a header file that provides variable and function definitions, i.e.:

/* myHeader.h */
int one = 1;
int someVar;

void someFunc()
{
....someVar = one;
}


Why would you do this? Does putting the function def in the header file force it to be inlined? Or is this just another bad thing to do but technically works?

Thanks.
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
Good question, the .h file should list them as "extern int somevar ; " and any initialization to values should be in the c /cpp file.

Of course you'll be told not to create global variables at all, but they're handy for things like const string tables.
 

dinkumthinkum

Senior member
Jul 3, 2008
203
0
0
I think it allows doubly defined variables so long as the definitions are the same type and they are uninitialized. Then there is really no conflict, it is just a certain amount of space reserved in the bss. But yes, you should stick to extern variables and function prototypes in headers for least confusion. The only way a function definition should appear in a header is if it is marked as "static inline".

It might work to do otherwise, remember that "#include" is simply asking for the contents of the file to be inserted verbatim. So you can get away with doing weird things on small projects.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: dinkumthinkum
I think it allows doubly defined variables so long as the definitions are the same type and they are uninitialized. Then there is really no conflict, it is just a certain amount of space reserved in the bss. But yes, you should stick to extern variables and function prototypes in headers for least confusion. The only way a function definition should appear in a header is if it is marked as "static inline".

It might work to do otherwise, remember that "#include" is simply asking for the contents of the file to be inserted verbatim. So you can get away with doing weird things on small projects.

There is a conflict. Two variables, in C, named the same thing in the same scope are symbol referencing errors. That said, I have seen some compilers, that shall remain nameless, that go out of their way to understand wtf a programmer is 'trying to do' by declaring a variable in a header, and 'doing the right thing' anyway.

However, according to Hoyle, a C prototype of a global variable should be declared extern in a header. That way, a named piece of memory exits in only one object file at link-time, and therefore, there are no symbolic conflicts.

All of that goes away in C++ with C++-style linkage, but in that case, there really are two different variables, which have the same source-level name but different link-level names.
 

duragezic

Lifer
Oct 11, 1999
11,234
4
81
Well, I guess the compiler I am using allows it.

I did a simple test, where a global variable is defined in both the c file and the header file. I ran it through a debugger and both variables were identical (same address).
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: degibson
Originally posted by: dinkumthinkum
I think it allows doubly defined variables so long as the definitions are the same type and they are uninitialized. Then there is really no conflict, it is just a certain amount of space reserved in the bss. But yes, you should stick to extern variables and function prototypes in headers for least confusion. The only way a function definition should appear in a header is if it is marked as "static inline".

It might work to do otherwise, remember that "#include" is simply asking for the contents of the file to be inserted verbatim. So you can get away with doing weird things on small projects.

There is a conflict. Two variables, in C, named the same thing in the same scope are symbol referencing errors. That said, I have seen some compilers, that shall remain nameless, that go out of their way to understand wtf a programmer is 'trying to do' by declaring a variable in a header, and 'doing the right thing' anyway.

However, according to Hoyle, a C prototype of a global variable should be declared extern in a header. That way, a named piece of memory exits in only one object file at link-time, and therefore, there are no symbolic conflicts.

All of that goes away in C++ with C++-style linkage, but in that case, there really are two different variables, which have the same source-level name but different link-level names.

This is WRONG.

Two variables with the same name and scope in C are SHARED. They are only name conflicts in C++, assuming they're not properly decorated with extern.

Sorry for the confusion.

EDIT: That stuff about C++ linkage applies only to mangled names, not global names.
 

duragezic

Lifer
Oct 11, 1999
11,234
4
81
Originally posted by: degibson
Originally posted by: degibson
Originally posted by: dinkumthinkum
I think it allows doubly defined variables so long as the definitions are the same type and they are uninitialized. Then there is really no conflict, it is just a certain amount of space reserved in the bss. But yes, you should stick to extern variables and function prototypes in headers for least confusion. The only way a function definition should appear in a header is if it is marked as "static inline".

It might work to do otherwise, remember that "#include" is simply asking for the contents of the file to be inserted verbatim. So you can get away with doing weird things on small projects.

There is a conflict. Two variables, in C, named the same thing in the same scope are symbol referencing errors. That said, I have seen some compilers, that shall remain nameless, that go out of their way to understand wtf a programmer is 'trying to do' by declaring a variable in a header, and 'doing the right thing' anyway.

However, according to Hoyle, a C prototype of a global variable should be declared extern in a header. That way, a named piece of memory exits in only one object file at link-time, and therefore, there are no symbolic conflicts.

All of that goes away in C++ with C++-style linkage, but in that case, there really are two different variables, which have the same source-level name but different link-level names.

This is WRONG.

Two variables with the same name and scope in C are SHARED. They are only name conflicts in C++, assuming they're not properly decorated with extern.

Sorry for the confusion.

EDIT: That stuff about C++ linkage applies only to mangled names, not global names.
What do you mean by "shared"?
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: duragezic

What do you mean by "shared"?

Sorry for the bad use of an oft-overloaded term. In this case, I meant:
Shared = all identically-named instances of the variable link to a single memory location. "Shared" between all files that can scope the name.
 
Sep 29, 2004
18,656
68
91
I hope this is C only code, not C++. If classes (C++) are available, globals should not be used except for the times where they are required.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: IHateMyJob2004
I hope this is C only code, not C++. If classes (C++) are available, globals should be used except for the times where they are required.

Indeed it is. Hence my initial confusion over the link semantics ;)
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
Originally posted by: IHateMyJob2004
I hope this is C only code, not C++. If classes (C++) are available, globals should be used except for the times where they are required.

Do you mean NOT used except for when required?

 
Sep 29, 2004
18,656
68
91
Originally posted by: Common Courtesy
Originally posted by: IHateMyJob2004
I hope this is C only code, not C++. If classes (C++) are available, globals should not be used except for the times where they are required.

Do you mean NOT used except for when required?

Fixed :)

degibson,
Looks like you are dealing with some veteran programmers that are new to C++. You often see messes when someone has 10 years experience in C then they are told to start using C++. One day this will be you though.

 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: IHateMyJob2004
degibson,
Looks like you are dealing with some veteran programmers that are new to C++. You often see messes when someone has 10 years experience in C then they are told to start using C++. One day this will be you though.

Ha ha. Every time I work on a project in C and then switch to C++ for something else I find that I have managed to pollute my C++ software engineering skills.