Hi,
Here's some code that produced a surprising result with GCC 4.3.3 on linux 64.
I'd have expected all addresses output to be the same.
I guess the reason for this is that when merging the templates instantiated in
one.cpp and two.cpp, the linker doesn't perform a complete merge, but only
merges for those methods that were instantiated in each translation unit. When
using the zero argument constructor one type is used, when using the one
argument constructor, another type is used.
As I understand it, the anonymous namespace has internal linkage, so Dummy
should be considered a different type in each unit, and the template
instantiations shouldn't really be merged. Under -O3 the addresses output are
the same. Whether this is due to separate templates or a single merged
template, I'm not sure.
I really just wanted to check that my understanding is correct. For the program
I was working on I use named namespaces to provide the right semantics.
Thanks for your time,
Stefan
-- nonsingleton.hpp
#ifndef NON_SINGLETON
#define NON_SINGLETON
#include
namespace {
class Dummy {};
}
template
class Singleton {
static ObjectT* object;
public:
static ObjectT& Instance() {
if (!object)
object = new ObjectT();
return *object; } };
template
ObjectT* Singleton::object = 0;
class NonSingleton {
typedef Singleton<> SingletonType;
public:
NonSingleton() {
std::cout << "0 arg constructor. Singleton: " <<
(&SingletonType::Instance()) << std::endl; }
NonSingleton(int i) {
std::cout << "1 arg constructor. Singleton: " <<
(&SingletonType::Instance()) << std::endl; }
~NonSingleton() {
std::cout << "Destructor. Singleton: " << (&SingletonType::Instance())
<< std::endl; } };
#endif
-- one.cpp
#include "nonsingleton.hpp"
void f() {
NonSingleton a; }
-- two.cpp
#include "nonsingleton.hpp"
int main() {
NonSingleton a;
NonSingleton b(1);
return 0; }
-- output
0 arg constructor. Singleton: 0x502010
1 arg constructor. Singleton: 0x502030
Destructor. Singleton: 0x502010
Destructor. Singleton: 0x502010