Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a non-static variable reside in a header file?

Take for example:

// myheader.h
static int myStaticVar = 0;
// If we remove 'static' the compiler will throw linker error.

void DoStuff();

// and myheader.cpp, and main.cpp;  etc

This is how I would explain it:

Static variables do not have external linkage, and when we compile without 'static' we are "including" the static variable (which is global here) in every file, which create duplicates and linker will throw an error since multiple declaration is not allowed.

Is there any better way to explain this? Thanks.

PS: Are we suppose to have static variables (not talking about members) in header file?

like image 427
CppLearner Avatar asked Oct 21 '11 08:10

CppLearner


People also ask

Why we Cannot access non static variables in static context?

Consequently, attempting to access a non-static variable from a static context (a static method or block) without a class instance creates ambiguity—every instantiated object has its own variable, so the compiler is unable to tell which value is being referenced.

Can static variables be used in header file?

A static variable should be declared with in the file where we use it shouldn't be exposed to header file.

Can a variable be defined in header?

ANSWER. Yes. Although this is not necessarily recommended, it can be easily accomplished with the correct set of macros and a header file. Typically, you should declare variables in C files and create extern definitions for them in header files.

What is a non static variable?

Non static variables are specific to that instance of a class. Static variable is like a global variable and is available to all methods. Non static variable is like a local variable and they can be accessed through only instance of a class.


2 Answers

Why can't a non-static variable reside in a header file?

Because it breaks the One Definition Rule(ODR).
When you include the header file containing a non-static variable, the declaration of the variable gets pasted in each source file where it is included. Thus you end up having more than one definition of a variable in same Translation Unit, this violates the ODR and hence the linker will give you linking errors.

How to explain static variables declared in header files?

When you declare a static variable in an header file, an copy of the variable gets created in each Translation Unit where the header file is included.

Declaring a static variable in header file will not give you multiple definition erros but it does not acheive your purpose of having a global variable whose value is shared accross all files which access it.

You may think that since you are using a global static variable its value will be retained accross different files, but as mentioned above each Translation Unit has its own copy of the variable and it does not acheive what you think you are acheiving.

Are we suppose to have static variables (not talking about members) in header file?

No,Never!

How do you declare and define global variables?

You need to use extern keyword.

Add the extern declaration of the variable in an header file. The header should be included by the one source file that defines the variable and by all the source files that reference the variable. Only one source file should define the variable. Also only one header file should declare the variable.

filename.h

extern int gVariable;  /* Declaration */ 

file1.cpp

#include "filename.h"  

/* Definition */ 
int gVariable = 37;    

void doSomething(void) 
{ 
    return gVariable++; 
} 

file2.cpp

#include "filename.h" 
#include <stdio.h>  
void doSomethingWithGlobal(void) 
{     
    printf("Global variable: %d\n", gVariable++); 
} 
like image 175
Alok Save Avatar answered Oct 13 '22 12:10

Alok Save


First, read this answer to a similar question.

To complement the answer based on your question, here goes:

When you #include a file (any file, .h files is a common convention), it almost basically just copy-pastes it in your code. If you have non-static variable in the header file and you include it in two source files, the variable gets copy-pasted in both source files and well you get a link error as I explained in the answer I told you to read above.

If you want to share a global variable across many source files, you should do this:

In only one of your source files:

type global_var = default_value;

In the header file:

extern type global_var;

So, this way, all the source files see there is going to be a global_var somewhere in the bunch of source files. Only one of the source files actually contains that variable and when linking happens, all the source files would be referring to that one instance of global_var

like image 32
Shahbaz Avatar answered Oct 13 '22 11:10

Shahbaz