Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

Undefined references for extern variable in namespace

Bastian_B_
New Contributor I
2,320 Views

Hello,

When trying to compile this code:

File main.cc:

#include <iostream>

namespace NS { void print(); }

using namespace NS;

void NS::print() {
  extern int a;
  std::cout << a << std::endl;
}

int main(int argc, char** argv) {
  NS::print();
  return 0;
}

File b.cc:

namespace NS {
  int a = 3;
}

I find that the icpc emits undefined references to the symbol 'a' while GCC and Clang compile and link without problems. This is on Linux x86_64 using ICC version 16.0.3 with GCC 4.9 as backend.

 

 

g++ -o gcc_main.o -c main.cc
g++ -o gcc_b.o -c b.cc
g++ -o gcc_extern gcc_main.o gcc_b.o


icpc -o icc_main.o -c main.cc
icpc -o icc_b.o -c b.cc
icpc -o icc_extern icc_main.o icc_b.o


icc_main.o: In function `main':
main.cc:(.text+0x2d): undefined reference to `a'
icc_main.o: In function `NS::print()':
main.cc:(.text+0x58): undefined reference to `a'

It looks like icpc emits an unresolved symbol for "a" into main.o while g++ puts "NS::a" into main.o as unresolved. The latter is then available at link time but the former is not.

Thanks for your help

Bastian 

0 Kudos
3 Replies
Bastian_B_
New Contributor I
2,320 Views

We believe this is in violation with the C++ standard:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3242.pdf

The enclosing namespaces of a declaration are those namespaces in which the declaration lexically appears, except for a redeclaration of a namespace member outside its original namespace (e.g., a definition as specified in 7.3.1.2). Such a redeclaration has the same enclosing namespaces as the original declaration.

[Example: § 7.3.1 159 c ISO/IEC N3242=11-0012

 

namespace Q {

  namespace V {

    void f(); // enclosing namespaces are the global namespace, Q, and Q::V

    class C {

      void m();

    };

  }

  void V::f() { // enclosing namespaces are the global namespace, Q, and Q::V

    extern void h(); // ... so this declares Q::V::h

  }

  void V::C::m() {

    // enclosing namespaces are the global namespace, Q, and Q::V

  }

}

— end example ]

0 Kudos
Melanie_B_Intel
Employee
2,320 Views

Yes I agree with you. I've created DPD200411955 in our internal bugs database.

Thanks for reporting this problem.--Melanie

0 Kudos
Feilong_H_Intel
Employee
2,320 Views

This issue has been fixed in the latest 16.0 compiler update.  FYI.

0 Kudos
Reply