I'm using mingw-w64 on Windows 7 Pro 64-bit. In trying to access external variables, after much hair tearing, I finally arrived at this:
// MultiTest2.h
// Version 1.0.0
// MDJ 2016/04/13
#ifndef MULTITEST2_H
#define MULTITEST2_H
extern "C" {
int iXfer;
int setInt();
}
#endif // MULTITEST2_H
does NOT work (I'm using 'extern "C"' instead of just 'extern' because I'm working towards linking to assembly code eventually), but:
// MultiTest2.h
// Version 1.0.1
// MDJ 2016/04/13
#ifndef MULTITEST2_H
#define MULTITEST2_H
extern "C" int iXfer;
extern "C" int setInt();
#endif // MULTITEST2_H
DOES work!
FYI, the other two files in the system are:
// MultiTest2.cpp
// Version 1.0.0
// MDJ 2016/04/13
#include "MultiTest2.h"
int iXfer = 0;
int setInt() {
iXfer = 6253;
return 0;
}
and:
// MultiTest1.cpp
// Version 1.0.0
// MDJ 2016/04/13
#include <iostream>
#include "MultiTest2.h"
using namespace std;
int main() {
setInt();
cout << iXfer << endl;
}
With Version 1.0.0 of MultiTest2.h (the declarations in an 'extern "C"' block), immediately upon entering:
g++ -S MultiTest2.cpp
the result is:
MultiTest2.cpp:7:5: error: redefinition of 'int iXfer'
int iXfer = 0;
^
In file included from MultiTest2.cpp:5:0:
MultiTest2.h:12:6: note: 'int iXfer' previously declared here
int iXfer;
^
But, with Version 1.0.1 of MultiTest2.h (individual 'extern "C"' declarations), the following sequence works perfectly:
c:\work\gccWork\MultiTest>g++ -S MultiTest2.cpp
c:\work\gccWork\MultiTest>g++ -S MultiTest1.cpp
c:\work\gccWork\MultiTest>g++ -c MultiTest2.s
c:\work\gccWork\MultiTest>g++ -c MultiTest1.s
c:\work\gccWork\MultiTest>g++ -o MultiTest.exe MultiTest2.o MultiTest1.o
c:\work\gccWork\MultiTest>MultiTest
6253
Is this some sort of mingw-w64 idiosyncracy, or is there something I'm missing here?
They are not the same.
extern "C" int foo;
Does TWO things: it declares that foo is extern (i.e. this is a declaration only, and the symbol will be defined by another module), and it declares the linking of foo as "C", which influences the symbol name.
On the other hand,
extern "C" {
int foo;
}
only declares that foo has C linking. It does not declare the symbol as extern, which means that this is a definition, not just a declaration.
In other words
extern "C" int foo;
is the same as (note the repetition of the extern keyword)
extern "C" {
extern int foo;
}