Reputation: 308
I have an annoying warning from clang
version 9.0.0.
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
(g++
give me a similar warning "X used but never defined")
Others questions are talking about inline
or static
function, but it's not my case.
Here is a minimal not-working example :
:::::::::::::: A.cpp ::::::::::::::
#include "B.hpp"
namespace {
class A {
public:
bool foo(int& bar) {
B* b = new B(&bar);
return 0;
}
};
}
int main() {
return 0;
}
:::::::::::::: B.cpp ::::::::::::::
#include "B.hpp"
namespace {
B::B(int* b) : b(b) {};
}
:::::::::::::: B.hpp ::::::::::::::
#ifndef B_HPP
#define B_HPP
#pragma once
namespace {
class B {
public:
B(int* b);
private:
int* b;
};
}
#endif // B_HPP
... compiled with
clang++ A.cpp B.cpp
Here is the warning from clang
:
function '(anonymous namespace)::B::B' has internal linkage but is not defined [-Wundefined-internal]
My question is : why the constructor B
is not recognized ?
Upvotes: 2
Views: 3558
Reputation: 238361
namespace {
This is an anonymous namespace. Anonymous namespaces are special. The anonymous namespace of each translation unit is unique: The anonymous namespace in A.cpp is completely different from the one in B.cpp.
B(int* b);
This line declares the constructor of B
which is declared within the anonymous namespace.
B* b = new B(&bar);
This line invokes the constructor within A.cpp. Unless (anonymous namespace of A.cpp)::B::B
is defined, the program is ill-formed.
B::B(int* b) : b(b) {};
This defines (anonymous namespace of B.cpp)::B::B
. Notice that this function, as well as the class itself is unrelated to the one in the other translation unit.
Since there is no definition for (anonymous namespace of A.cpp)::B::B
, the program is ill-formed.
All functions with internal linkage (that are odr-used) must be defined in the same translation unit where they are used, because they cannot be defined anywhere else. Functions have internal linkage if they are declared static in the namespace scope (static has different meaning in class scope), or if they are declared in an anonymous namespace.
Upvotes: 7