Why do I need an include file for extern variables? - c++

I found this:
How do I use extern to share variables between source files?
and its main answer is rather clear to me.
However I do not understand why this gives me an error:
x.h :
#pragma once
namespace x {
class A {
public: void func() const;
};
// extern A const a; // cannot move this out of the include file !!!
// extern int xi; // fine to remove from here
}
--- main.cpp ---
#include "stdafx.h"
#include "x.h"
namespace x { extern int xi; extern const A a ; } // instead of include file
extern int i;
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << i << std::endl; // works
std::cout << x::xi << std::endl; // works
x::a.func();
return 0;
}
--- x.cpp ---
#include "stdafx.h"
#include "x.h"
namespace x
{
void A::func() const
{ std::cout << "x::A::func() called" << std::endl; }
const A a; // Problem if const
int xi = 234; // works
}
int i = 123; // works
error LNK2001: unresolved external symbol "class x::A const x::a" (?a#x##3VA#1#B)
(VisualStudio 2013)
Compiling the two files is fine, and I can build and run it if I remove the const keyword, or if I move the extern statement into the include file.
Thanks for an explanation (can't believe in a compiler bug) ;)

Namespace-scope const variables default to internal linkage (i.e., visible only within that translation unit). The extern is needed to override the default and give it external linkage (so that it can be accessed from a different translation unit).

Related

Why do I not need to include main.cpp?

In the small example needsExtern.cpp needs the definition of global::bar. needsExtern.cpp would normally include the file with the definition (in this case main.cpp). However, since the file is main.cpp it is not needed.
Why does needsExtern.cpp not need to include main.cpp?
needsExtern.h
struct NeedsExtern
{
NeedsExtern();
};
needsExtern.cpp
#include "needsExtern.h"
#include <iostream>
namespace global
{
extern const int bar;
}
NeedsExtern::NeedsExtern()
{
std::cout << global::bar << "\n";
}
main.cpp
#include "needsExtern.h"
namespace global
{
extern const int bar{26};
}
void main()
{
NeedsExtern ne;
}
This is precisely where extern is invented for: the compiler just assumes the variable is defined elsewhere in the project. You can read more about this principle here.

c++ extern unresolved symbol error LNK2001

I have something like this:
--includes.h
extern int count;
--main.cpp
#include "includes.h"
int count = 4;
--other.cpp
#include "includes.h"
cout<<count; // will output 4
but when I did this, the compiler errors out with the following message:
error LNK2001: unresolved external symbol "int count" (?count##3HA)
Any idea why I am getting this?
What is the best way to share variables across different files?
How can I define use a variable in one file, and modify that same variable in another file?
main.cpp
#include <iostream>
int y;
int testy();
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << y;
std::cout<<testy();
std::cout << y;
return 0;
}
source.cpp
extern int y;
int testy(){return y++;}
This should help understand your issue...
You can try to put in into unnamed namespace
namespace{
extern int count = -1;
};
cpp:
std::cout << count;
You should define an extern int in a header and a int into one file, but this file should be without any reference to the header

LNK2001 error using extern int

I have this simple example and I can't get it to compile:
Three files: my.h, my.cpp, and use.cpp:
//my.h
extern int foo;
void print_foo();
void print(int);
//my.cpp
#include "my.h"
#include "../../stb_lib_facilities.h" //inlcudes cout, cin, etc
void print_foo(){
cout << foo << endl;
}
void print(int i){
cout << i << endl;
}
//use.cpp
#include <iostream>
#include "my.h"
int main(){
foo = 7;
print_foo();
print(99);
return 0;
}
When I try to compile it I get three errors:
LNK2001: extern "int foo"..
LNK2019: extern "int foo"..
LNK1120:
What am I doing wrong?
Thanks for any help
You do not have any definition of your global variable. In any of your .cpp files, but just in one of them, you should add this:
int foo = 0; // This is a definition
Your declaration:
extern int foo; // This is a declaration
Only tells the compiler that such a global variable exists, but then there is no place where you actually define it. Therefore, the linker will eventually complain that you have an undefined referenced symbol.

extern strange behaviour [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
const and global
This code will produce error in c++
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
Reason as given by many is global const has internal scope and it is default static.
solution to this is :-
//Foo.h
extern const int Foo;
// Foo.cpp
#include "Foo.h"
const int Foo = 99;
// Main.cpp
#include "Foo.h"
int main()
{
cout << Foo << endl;
}
I used to think that extern is used to tell compiler that memory for the indentifer is already allocated somewhere in other files.
Applying same logic on above code can anyone explain what is happening here or extern has different meaning in c++??
enter link description here
Also consider this page it is spoiling my all intuitions..
Added an extern ... line to the CPP, which - I think - kills the internal linkage behavior of the next line.
// Foo.cpp
extern const int Foo;
const int Foo = 99;
Also made some unrelated corrections to Main:
// Main.cpp
#include <iostream>
extern const int Foo;
int main()
{
using namespace std;
cout << Foo << endl;
return 0;
}
They are #include <iostream> and using namespace std;.
This answer is not carefully reasoned theoretically, but works for me with g++.

operator declaration within namespace in a header?

Please excuse me but I didn't know to give a name to the title in a short way.
Why do I need to declare an overloaded operator inside the header to make it work in this example:
HEAD.H
#pragma once
namespace test {
class A {
public:
A() : x(0) {}
int x;
};
A& operator++(A& obj); //this is my question
}
HEAD.CPP
#include "head.h"
namespace test {
A& operator++(A& obj) {
++obj.x;
return obj;
}
}
MAIN.CPP
#include <iostream>
#include "head.h"
using namespace std;
using namespace test;
int main() {
A object;
++object; //this won't work if we delete declaration in a header
return 0;
}
operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header?
Thank you.
The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).
Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.
Simple example with namespaces:
#include <iostream>
namespace test{
int f() { return 42; }
int g() { return -1; }
}
namespace other{
int f() { return 1024; }
}
using namespace other;
int main(){
//error: 'g' was not declared in this scope
//std::cout << g() << std::endl;
std::cout << test::f() << std::endl; //42
std::cout << f() << std::endl; //1024
return 0;
}