I have a global variable in one of the cpp files, where I am assigning a value to it. Now in order to be able to use it in another cpp file, I am declaring it as extern and this file has multiple functions that use it so I am doing this globally. Now the value of this variable can be accessed in one of the functions and not in the other one. Any suggestions except using it in a header file would be good because I wasted 4 days playing with that.
Sorry, I'm ignoring the request for answers suggesting anything other than the use of header files. This is what headers are for, when you use them correctly... Read carefully:
global.h
#ifndef MY_GLOBALS_H
#define MY_GLOBALS_H
// This is a declaration of your variable, which tells the linker this value
// is found elsewhere. Anyone who wishes to use it must include global.h,
// either directly or indirectly.
extern int myglobalint;
#endif
global.cpp
#include "global.h"
// This is the definition of your variable. It can only happen in one place.
// You must include global.h so that the compiler matches it to the correct
// one, and doesn't implicitly convert it to static.
int myglobalint = 0;
user.cpp
// Anyone who uses the global value must include the appropriate header.
#include "global.h"
void SomeFunction()
{
// Now you can access the variable.
int temp = myglobalint;
}
Now, when you compile and link your project, you must:
Compile each source (.cpp) file into an object file;
Link all object files to create your executable / library / whatever.
Using the syntax I have given above, you should have neither compile nor link errors.
Related
I am using GCC C++ 11 in CodeBlocks IDE. I have been trying to reuse classes that I wrote by putting them into a header file but it doesn't work. I have looked into many books but none has detailed information on making C++ code reusable.
There are a couple concepts that C++ uses that I think you're missing:
The difference between a declaration and a definition
#include statements
Linking against other libraries
In general, one reuses code in C++ by Declaring a function in a header file (.h), Defining it in a source file (.cpp). The header file ("foo.h") is then included in both the source file (foo.cpp) and any other file you want to use something declared in it using and preprocessor include directive #include "foo.h". Finally if the source file in which the functions declared in the header file are defined is not a part of the source for the library or executable that you're compiling, you will need to link against the library in which it was built.
Here's a simple example that assumes that you don't need to link against an external library and that all files are in the same directory:
foo.h:
The class Foo is declared along with a member function foobar and a private member variable barM. In this file we're telling the world that there is a class named Foo, it's constructor and destructor are public, it has a member function named fooBar that returns an integer and it also has a private member variable named barM.
class Foo
{
public:
Foo();
~Foo();
int fooBar();
private:
int barM;
};
foo.cpp
The individual member functions for our class Foo are defined, we implement the things we declared in the header file. Notice the include statement at the top
#include "foo.h"
Foo::Foo()
{
barM = 10;
}
Foo::~Foo()
{
}
int Foo::fooBar()
{
return barM;
}
main.cpp
We use our class in a different file, again the header file is included at the top.
#include <stdio.h>
#include "foo.h"
int main(int argc, char *argv[])
{
Foo flub;
std::cout << "flub's fooBar is: " << flub.fooBar() << std::endl();
return 0;
}
The expected output from this would be:
flub's fooBar is 10.
As a general note, I haven't compiled this code, but it should be enough to give you a basic example of the ideas of declarations, definitions, and include statements.
Seeing as you're coming from Java, I'm actually betting that you got all of that already, the hard part is actually using code from a different c++ library, which is akin to Java packages. Setting this up requires exporting the symbols you desired to use in a different library. The way to do this is compiler specific, but is generally accomplished by defining a Macro in a different header file and then using that macro in the declaration of the item you'd like to export. For gcc, see reference GNU Reference Manual.
To extend the above example you create another header file: fooLibExport.h
#if BUILDING_LIBFOO && HAVE_VISIBILITY
#define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default")))
#elif BUILDING_LIBFOO && defined _MSC_VER
#define LIBFOO_DLL_EXPORTED __declspec(dllexport)
#elif defined _MSC_VER
#define LIBFOO_DLL_EXPORTED __declspec(dllimport)
#else
#define LIBFOO_DLL_EXPORTED
#endif
foo.h would then be changed to:
#include "fooLibExport.h"
class LIBFOO_DLL_EXPORTED Foo
{
public:
Foo();
~Foo();
int fooBar();
private:
int barM;
};
Finally you'll need to link against the library that Foo was built into. Again this is compiler specific. At this point we're through the setting up of header files for exporting symbols from a C++ library so that functions defined in one library can be used in another. I'm going assume that you can follow the reference material for setting up the GCC compiler for the rest of the process. I've tried to bold the key words that should help refine your searches.
One final note about #include statements, the actual argument isn't just the filename, its the path, relative or absolute, to the file in question. So if the header file isn't in the same file as the file you're trying to include it in, you'll need to use the appropriate path to the file.
Code re-usability casts its net wide in C++ terminology. Please be specific what do you mean by it.C and C++ programming language features usually considered to be relevant to code reuse could be :-
functions, defined types, macros, composition, generics, overloaded functions and operators, and polymorphism.
EDITED IN RESPONSE TO COMMENT:-
Then you have to use header files for putting all declarations which you can use in any file just by including this.
I'm developping a Blackberry 10 mobile app. using the momentics IDE (BB Native SDK).
In my application, I want to use global variables that will be shared by many classes.
I tried the code below like described in this link, but when I add the extern instruction before the declaration of the variable "g_nValue* " in the ".h" file, it returns the error "storage class specified for 'g_nValue'"
*/ global.cpp:
// declaration of g_nValue
int g_nValue = 5;
*/ global.h:
#ifndef GLOBAL_H // header guards
#define GLOBAL_H
// extern tells the compiler this variable is declared elsewhere
extern int g_nValue;
#endif
Any one have an idea on this? I searched a lot and they all said that the extern instruction should not cause any trouble.
An alternative to extern are static variables inside a class:
//.h
struct Globals
{
static int g_global_var;
};
//.cpp
int Globals::g_global_var = 0;
//usage:
Globals::g_global_var;
the extern qualifier only tells the compiler, "this symbol is defined in a different source file" - so the symbol exists, it's safe to use it. You will get a linking error if you actually "lie" about it and don't define the symbol - but that's a different story.
There does not seam to be any problem with the code you showed us.
But here is a link which might help you get a better idea...
You don't declare the variable exteren in the compilation unit it's defined in. You only declare it extern (and don't define it) if you want to use it in other .cpp files (compilation units).
Your code seems fine. Maybe the you have an error elsewhere. Maybe there is a semicolon (;) missing in a line before extern int g_nValue.
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?
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++);
}
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
The header file (.h) tells you (declares) what the definition file (.cpp) will do.
For a metaphor - a header file is like to telling a lot of friends that you are going to do something, but in reality you are going to do it once.
I have 3 cpp files that look like this
#include "Variables.h"
void AppMain() {
//Stuff...
}
They all use the same variables inside them so they have the same headers but I get stuff like this
1>OnTimer.obj : error LNK2005: "int slider" (?slider##3HA) already defined in AppMain.obj
Why is that?
Keep in mind that a #include is roughly like cutting and pasting the included file inside the source file that includes it (this is a rough analogy, but you get the point). That means if you have:
int x; // or "slider" or whatever vars are conflicting
in the header file and that header file is included by three source files in a program, then they will all have a global named x defined that will conflict.
What you want to do is define the variable as extern so that the .cpp files will all get the declaration, and then in ONE of your .cpp files give the actual definition.
in Variables.h:
extern int x;
in SomeSourceFile.cpp
int x;
Of course, I'd recommend against globals, but if you must use them this would keep them from conflicting.
This is because the compiler compiles each .cpp file separately, creating a .obj file for each one. Your header appears to have something like:
int slider;
When this is included into each of your three .cpp file, you get three copies of the int slider variable, just as if you had declared it in each .cpp file. The linker complains about this because you haven't have three different things with the same name.
What you probably want to do is change your header file to read:
extern int slider;
This tells the compiler that there is a slider variable somewhere, but possibly not here, and lets the linker figure it out. Then, in one .cpp file:
int slider;
gives the linker one actual variable to link.
Because "int slider" is already defined in another file? Check that you have header guards...
#ifndef _VARIABLES_H_
#define _VARIABLES_H_
int slider;
#endif
If it is across multiple translation units, and you do want the variables to be different (ie not global), then maybe declare them in an anonymous namespace:
namespace {
int slider;
}
If you do want them global, look to James' solution.
What is happening is that each of the variables from Variables.h are given global scope for each of the individual c files. When the linker compiles all the c files, it sees multiple variables with the same name.
If you are wanting to use variables from the header file as global variables, then you will have to use the keyword "extern" in front of all of them, and in the main file don't use the keyword extern.
main c:
int n_MyVar;
other files:
extern int n_MyVar;
You can create two files Variables.h and EVariables.h, or just declare the variables in the main.cpp file.
A much better way to do this is to create a class of Variables and pass a reference to the class.
I know that this is an old thread, but I came across this as one of the first search results from Google. I solved the problem by placing the variable static.
namespace Vert
{
static int i;
}
I tried extern and in my situation that didn't seem to solve the problem.
This linking error can also be avoided if the variables included multiple times via the "Variables.h" are declared as const.
I had this error too although I work with extern definitions. The problem was initializing the variables in the extern definitions too:
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader = nullptr; // here's the problem
=> error
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader; // without initializing
=> no error, problem solved
In the process of changing some code, I have spilt some functions into multiple files. I have the files controls.cpp and display.cpp and I would like to be able to have access to the same set of variables in both files. I don't mind where they are initialized or declared, as long as the functions in both files can use them.
This was not an issue when the functions were in the same file, but now it seems almost impossible after an hour of googling and trying various things.
Define the variable in one file like:
type var_name;
And declare it global in the other file like:
extern type var_name;
use those variables as extern
i.e.
extern int i;
in another file declare same as normal global variable...
int i;//global
Create two new files:
Something like Globals.h and declare all variables like: extern type name;
btw remember include guards.
Something like Globals.cpp and declare variables like: type name;
Then add #include "Globals.h" at the top of:
Globals.cpp
controls.cpp
display.cpp
You may then want some functions to initialise them.
Essentially all you have to do is declare the variable once in one code file, and declare it in the others as extern (making sure NOT to initialize it when you are declaring it extern, or some compilers will ignore the extern keyword, giving you compiler errors.)
The simplest way to do this is to use a macro in a header file, like such:
#pragma once
#ifdef __MAIN__
#define __EXTERN(type, name, value) type name = value
#else
#define __EXTERN(type, name, value) extern type name;
#endif
and then declare your variables in that same header file, like such:
__EXTERN(volatile int, MyVolatileInteger, 0);
from any ONE file in the project, include the header file, like such:
#define __MAIN__
#include "Globals.h"
from all the rest, just simply include it normally, like such:
#include "Globals.h"
Presto, you're done. Variables only declared once, and initialized in-line. This is very maintainable, and saves you the trouble of having to declare everything twice.
All of the declarations you want visible in multiple compilation units (.cpp files), should go into a header file that you include in all places that need to use the variable, type, class, etc.
This is vastly better than extern, which essentially hides your intention to share the declaration.