Search code examples
c++visual-studio-2013icc

Extern in class function


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 :)


Solution

  • 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.