I read over a few articles about this, and am taking a few introductory courses to C++ concurrently. All of the courses I am taking and these articles just don't help me understand how to implement the extern and static extern storage class. I don't feel comfortable moving on until I really have a grasp on this, even though what I am seeing from other programmers is that they do not use these storage classes, but use inheritance from a header file and local static storage class to use a static variable in a function. Both of those instances I can do. I figured out how to use the static storage class both within the same source file and also by inheriting the static variable from an inherited source file.
I keep getting linker and / or compiler errors.
I am using Visual Studio 2015 Community Edition with C++11, and have CodeDroid in Android with C++98.
Will someone please teach me how to use the extern and static extern storage classes without linker and compiler errors?
For example, say I had one.cpp and two.cpp. Say I have an int main() function in one.cpp. Say I want to demonstrate outputting the value of an extern int in the main() function. And, say I have a void function called extFuncExample() declared and defined in one.cpp, and also want to output its value there.
A course I am taking has extern and static extern as two different storage classes. So, if you would be so kind as to break this down to me, so I can output these values without compiler and linker errors.
Thank you so much!
one.cpp
#include <iostream>
#include "Two.cpp"
int main()
{
extern int global_int;
std::cout << "global_int = " << global_int << '\n';
return 0;
}
two.cpp
#include <iostream>
int global_int = 100;
This, I found works. I was including #include "two.cpp" in one.cpp and also using the extern storage class which was causing the issues. Removed #include "two.cpp" and it worked!
In C and C++ there is a difference between a (forwards) declaration and a definition of symbols. extern is used to forwards declare the existence of a symbol which is external to the translation unit, that is: to 'import' symbol from "somewhere" and "make it visible" to the code being compiled. At link time the references to external symbols are resolved.
Effectively extern is a way to instruct the compiler/toolchain that it should not expect to find the symbol definition among the code being compiled, but instead should look in the libraries being linked against to find it. The linker will not bother to do so for symbols that aren't declared extern.
Apart from that, there is a somewhat common mistake that people make with extern: to use it to declare a global variable and also define it inside a header. For example:
// some header.h
extern int my_global = 40; // = 40 makes this wrong.
Then they proceed to include it multiple times in different translation units (source files):
// file1.c{pp}
#include "header.h"
// file2.c{pp}
#include "header.h"
At this point you have introduced multiple definitions for the same symbol in your program because #include simply copies the contents of the header verbatim into the context at which the #include is performed. The compiler will still compile the code, but the linker will refuse to link it because of the multiple definition error.
Related
There are other questions about using extern and const in C++. I also have read about internal and external linkage (it is been a while since I used C++) But I would appreciate if someone reminds to me about the usage of the following particular situation.
I have two cpp files: Description.cpp and Register.cpp and one hpp file: Description. h .They are something like this
//Description.cpp
#include "Description.hpp"
extern const FD models[];
//some other code
.
//Register.cpp
#include "Description.hpp"
extern const FD models[2]={
{"elementA",{1,2}},
{"elementB",{3,4}}
};
.
//Description.hpp
struct FD{
string name;
double v[2];
};
I am wondering why the extern keyword is necessary in Register.cpp
As discussed in the comments, by default, a const object has internal linkage, meaning you can only see it from the file you define it in. To change that, you use the keyword extern, which means "this variable can be seen from other files". Therefore, in Register.cpp, you need extern to tell the linker to make this visible elsewhere, and in Description.cpp you need extern to tell the compiler it might be defined elsewhere.
A better solution would be to move the declaration extern const FD models[]; into a .hpp file (either Description.hpp or a new Register.hpp, depending on details of your project). Then in Description.cpp and any other code that uses models, you include that file and don't need the declaration at all. In Register.cpp, you also include this header. Then the compiler knows that models has external linkage and you don't need to say extern again.
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 am currently looking through the code written by senior engineer. The code works fine but i am trying to figure out one detail.
He uses quite a few global variables and his code is broken down into a lot of separate files. So he uses a technique to make sure that global vars are declared everywhere where he needs to access them but are only defined once.
The technique is new to me but I read few articles on the internet and got some understanding about how it works. He uses
#undef EXTERN
followed by conditional definition of EXTERN as an empty string or actual extern. There is a very good article here explaining how it works. Also there is a discussion here
What gets me confused is that all examples I saw on the web suggest to include header file in a regular way in all of the source files that need it except for one. In this single special case line that includes header is preceded by definition of a symbol that will ensure that EXTERN will be defined to an empty string and .. so on (see link above). Typically this single special case is in main or in a separate source file dedicated to the declaration of global variables.
However in the code that I am looking at this special case is always in the source file that corresponds the header. Here is the minimal example:
"peripheral1.h" :
#undef EXTERN
#ifndef PERIPHERAL_1_CPP
#define EXTERN extern
#else
#define EXTERN
#endif
EXTERN void function1(void);
"peripheral1.cpp" :
#define PERIPHERAL_1_CPP
#include "peripheral1.h"
function1()
{
//function code code here
}
Everywhere else in the code he just does
#include "peripheral1.h"
My question is how and why does that work? In other words, how does compiler know where to define and where to just declare function (or variable, or class ...)? And why is it ok in above example to have the lines :
#define PERIPHERAL_1_CPP
#include "peripheral1.h"
in actual peripheral1.cpp rather then in main.cpp or elsewhere?
Or am I missing something obvious here?
All the source files, except "perripheral1.cpp", after preprocessing contain a sequence
of external variable declarations like:
extern int a;
extern int b;
extern int c;
In peripheral1.cpp only, after preprocessing, there will be a sequence of declarations:
int a;
int b;
int c;
int d;
which are tentative definitions of the corresponding variables, which, under normal circumstances are equivalent of the external definitions :
int a = 0;
int b = 0;
int c = 0;
int d = 0;
End result is, variable are declared everywhere, but defined only once.
PS. To be perfectly clear ...
In other words, how does compiler know where to define and where to
just declare function (or variable, or class ...)?
The compiler knows where to declare, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a declaration.
The compiler knows where to define, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a definition.
In other other words, the compiler does not know - you tell it explicitly what you want it to do.
Nostalgia
Ahh, this takes me back a fair way (about 20 years or so).
This is a way for C code to define global variables across multiple files: you define the variable once using a macro to ensure it is defined exactly only once, and then extern it in other C code files so you can utilise it. Nowadays it is quite superfluous in many instances, however it still has its place in legacy code, and will (most likely) still work in many modern compilers, nut it is C code not C++.
Normally the likes of #define PERIPHERAL_1_CPP is utilised to ensure uniquenesss of inclusion like a #pragma once
In my own code I would use something like:
#ifndef PERIPHERAL_1_CPP
#define PERIPHERAL_1_CPP
// my includes here
// my code here
#endif
That way you can #include the file as many times as you want all over your code, in every code file even, and you will avoid multiple definition errors. To be fair I normally do it with the .h files and have something like:
// for absolutely insane safety/paranoia
#pragma once
// normally sufficient
#ifndef PERIPHERAL_1_H
#define PERIPHERAL_1_H
// my includes here
// my code here
#endif
I have never tried it on cpp files but wil llater tonight to see if there is any benefit one way or the other:)
Give me a shout if you need any more info:)
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.
I have a global multidimensional array, g_iAllData[MAX_LEN][MAX_WIDTH] being used in a Form. When I write to it in a function: g_iAllData[iRow][iColumn]= iByte_Count; I can see in a Watch Window that it's contents are not being changed. If I put the array in the function, it works fine.
Is there something I'm missing? I am declaring it as global after my #include's at the top of the Form1.h file. I have multiple functions that are called by buttons being pressed and I need to write and read from the array in each function. It would be easier to keep it as global instead of passing it to each function.
UPDATE code:
ProgramName.cpp
#include "stdafx.h"
#include "Form1.h"
Form1.h
#include <iostream>
#include <string>
...
#pragma once
const int MAX_LEN = 4033;
const int MAX_WIDTH = 21;
int g_iAllData[MAX_LEN][MAX_WIDTH];
...
namespace ProgramName{
// later on
ReadFile();
void ReadFile(void)
g_iAllData[iRow][iColumn]= iByte_Count;
Your code sample really confirms that you have a problem with your variable declaration.
As #Graham hinted, the proper way to define globals is:
define the variable in a cpp file
declare the variable as extern in a header file
I.e.
//ProgramName.cpp
#include "stdafx.h"
#include "Form1.h"
int g_iAllData[MAX_LEN][MAX_WIDTH];
//Form1.h
#include <iostream>
#include <string>
...
#pragma once
const int MAX_LEN = 4033;
const int MAX_WIDTH = 21;
extern int g_iAllData[MAX_LEN][MAX_WIDTH];
This way the linker will find the definition of the global variable in exactly one compilation unit, and in all other compilation units which #include the header, it will be able to link the extern declarations to the correct variable definition.
Barring this, strange things may happen: you may get cryptic linker error messages complaining about multiple variable definitions, or you might even get multiple distinct variables in your app instead of one global variable - the latter explains why your method doesn't seem to change the contents of your variable.
Are you including Form1.h in other files too? If so, you need to use 'extern' in the other files.
If you defined your array in header file (as you code shows), then every time you include that header in a translation unit, you effectively define a separate "copy" of your array. This is not even supposed to compile, since you are defining multiple instances of the same external object (violation of ODR).
If you managed to compile it somehow (how?), then there's no way to say which instance of g_iAllData you are modifying and which instance the debugger shows you in the watch window. Could be different instances, which is why you don't see the change.
Objects with external linkage should not be defined in header files. You better reconsider your approach.