Reputation: 41
After reading static variables in an inlined function, I wrote this test program:
main.cpp:
#include <iostream>
#include "a.h"
#include "f.h"
void g();
int main()
{
std::cout << "int main()\n";
f().info();
g();
}
a.h:
struct A
{
A() { std::cout << "A::A()\n"; }
void info() { std::cout << this << '\n'; }
};
f.h: (singleton local to each compilation unit because of the unnamed namespace)
namespace {
inline A& f()
{
static A x;
return x;
}
}
g.cpp:
#include <iostream>
#include "a.h"
#include "f.h"
void g()
{
std::cout << "void g()\n";
f().info();
}
The problem is that I don't get the same results with different compilers:
g++ 4.8.2: OK
int main()
A::A()
0x6014e8
void g()
A::A()
0x6014d0
clang++ 3.7.0: OK
int main()
A::A()
0x6015d1
void g()
A::A()
0x6015c1
icpc 15.0.2: no call to A::A() inside g() !
int main()
A::A()
0x601624
void g()
0x601620
Is this a bug in icpc ? Is the behaviour of the program not defined ? If I replace "namespace {...}" with "static" in f.h, A::A() is called inside g() as expected. Shouldn't the behaviour be the same?
If I remove "namespace {...}" in f.h, A::info() prints the same object address in main() and g(), and A::A() is called only once (with all compilers) as expected.
Upvotes: 4
Views: 146
Reputation: 62613
Since C++11 mandates names in unnamed namespaces to have internal linkage, every translation unit should have it's own version of f()
and, as a result, it's own version of static A x
. So gcc and clang are correct.
Seems like icpc is not following C++11 standard and instead following C++03, which allowed those names to be declared with external linkage. Since when you explicitly make f()
internal by using static
icpc follows the suit, I have a strong suspicion this is simply a bug.
Upvotes: 3