Jac
Jac

Reputation: 41

static inlined function with static variables

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

Answers (1)

SergeyA
SergeyA

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

Related Questions