My simple code looks like:
a.cpp:
#include <iostream>
namespace asd
{
class B
{
public:
void ss()
{
extern int i;
std::cout << i;
}
};
}
int main()
{
asd::B e;
e.ss();
}
b.cpp:
int i = 4;
Is this code good with standard or no ? Visual Studio compiles it without errors but the Intel C++ compiler says: unresolved external symbol "int asd::i" (?i@asd@@3HA)
For more fun if i change b.cpp to:
namespace asd
{
int i = 4;
}
Then Visual Studio C++ 2013 says: unresolved external symbol "int i" (?i@@3HA)
But the Intel C++ compiler says ok :) What is the proper version of this code If I want to have this extern in class member function (is it legal ?) ?
Edit: The best results are, when we change b.cpp to:
namespace asd
{
int i = 4;
}
int i = 5;
Visual c++ prints 5, intel compiler 4 :)
It is legal to declare an extern
or a static
variable inside any function. Your fix of the b.cpp
where you put namespace around the definition of that extern
is the right fix, too.
Visual Studio C++ 2013 complains about a name outside the asd
namespace (check the demangler to see what these extra characters around the name i
represent). This is incorrect, because the declaration places i
into the namespace asd
.
C++ standard illustrates this in section 3.5.7. It is using an extern
function as an example, but it illustrates the rule of placement of the name in the enclosing namespace.
namespace X {
void p() {
q(); // error: q not yet declared
extern void q(); // q is a member of namespace X
}
void middle() {
q(); // error: q not yet declared
}
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q
The comments on lines 4, 9, and 11 show that the name declared with extern
inside the member function needs to be placed in the enclosing namespace. It is a good, self-contained test case illustrating a bug in Microsoft's compiler.