This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

template instantiation and anonymous namespaces



Hi,

I mistakenly sent this to the gcc mailing list, so I'm sorry for the double post. There was also a problem with the code missing template parameters, which is hopefully fixed - so with luck it should compile now. Anyway,

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 desired 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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]