Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a namespace alias change linkage?

Tags:

c++

From my understanding, global variables in a .cpp file get externally linked. Suppose there are two source files, a.cpp and b.cpp:

// a.cpp
namespace a_ns
{
  int foo;
}

// b.cpp
namespace b_ns
{
  int foo;
}

Now suppose both have right after namespace ns=a_ns; and namespace ns=b_ns; respectively. Will this trigger any undefined behaviour like there would be (I think) if both a.cpp and b.cpp just used the same namespace ns for foo?

like image 779
space_voyager Avatar asked Jan 29 '23 07:01

space_voyager


2 Answers

No. Your proposed alias does not change the fact that the variables have qualified names a_ns::foo and b_ns::foo, which are different.

like image 61
Kerrek SB Avatar answered Feb 08 '23 16:02

Kerrek SB


If you are using different namespaces for foo, then you introduce two different variables, i.e. a_ns::foo and b_ns::foo. Hence, there is no ambiguity, no conflict, and no undefined behaviour - just two different variables just as if you called the one foo and the other bar.

A namespace alias, even at global scope, does not introduce an ambiguity with other translation units, whereas a duplicate namespace-name would. Confer namespace aliases in this online c++ standard draft), which defines uniqueness for namespace-names within the program, but uniqueness for namespace aliases only within a declarative region:

7.3.2 Namespace alias

A namespace-name or namespace-alias shall not be declared as the name of any other entity in the same declarative region. A namespace-name defined at global scope shall not be declared as the name of any other entity in any global scope of the program. ...

Hence, a namespace alias namespace ns=a_ns introduced in a.cpp will be "visible" only in a.cpp, and namespace ns=b_ns introduced in b.cpp will be "visible" only in b.cpp. So each use of ns::foo will unambiguously refer to a_ns in a.cpp and b_ns in b.cpp, respectively.

But if you actually define the same namespace for foo in two different translation units, e.g. namespace ns { int foo; } in both a.cpp and b.cpp, each individual .cpp-file will be compiled correctly, but you will get a linker error, e.g. duplicate symbol __ZN2ns3fooE in: ../a.o; ../b.o.

like image 23
Stephan Lechner Avatar answered Feb 08 '23 17:02

Stephan Lechner