Web lists-archives.org

[Mingw-users] [BUG] - member is template<T>: ice in 4.2.1-sjlj (mingw32-2), bad compilation in 3.4.5




Hello all,


The problem seems to be related to having a member whose type is
template<T>. The AutoCounter class is used to track creation and
deletion of objects.

AutoCounter was not originally a template. The exercise is to turn it
into a template so that you can add a member to class T with type
AutoCounter<T>, so that its messages will have the parent type name
instead of "AutoCounter", e.g, "All MyType objects not cleaned up".

Compilation with gcc 3.4.5 is successful, but it crashes on the line:

verifier.add(this); // first line in AutoCounter();
If I comment out this line, the program will run, but the output
will be wrong.

If I compile with gcc-4.2.1-sjlj, I get an ICE:

c:\mingw4\bin\g++ -g -frtti -o test test.cpp

test.cpp: In destructor 'AutoCounter<T>::~AutoCounter() [with T = Outer]':
test.cpp:53:   instantiated from 'AutoCounter<Outer>::CleanupCheck AutoCounter<O
uter>::verifier'
test.cpp:53:   instantiated from 'AutoCounter<T>::~AutoCounter() [with T = Outer
]'
test.cpp:76:   instantiated from here
test.cpp:53: internal compiler error: in instantiate_decl, at cp/pt.c:12094

It compiles with Borland C++ 5.5 and gives the expected output:

created[0]
created[1]
destroying[0]
~CleanupCheck()
All Outer objects not cleaned up

Please see code below:
/**** TEST.CPP begins on line below ****/
//: C16:AutoCounter.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#ifndef AUTOCOUNTER_H
#define AUTOCOUNTER_H
//#include "../../require.h"
#include <iostream>
#include <set> // Standard C++ Library container
#include <string>

template <class T>
class AutoCounter {
  static int count;
  int id;
  class CleanupCheck {
    std::set<AutoCounter*> trace;
  public:
    void add(AutoCounter* ap) {
      trace.insert(ap);
    }
    void remove(AutoCounter* ap) {
      std::string s = std::string("Attempt to delete ")
                    + std::string(typeid(T).name())
                    + std::string(" twice");
      // require(trace.erase(ap) == 1, s.c_str());
      if (trace.erase(ap) != 1)
         cout << s << endl;
    }
    ~CleanupCheck() {
      std::cout << "~CleanupCheck()"<< std::endl;
      std::string s = std::string("All ") + std::string(typeid(T).name())
                    + std::string(" objects not cleaned up");
      // require(trace.size() == 0, s.c_str());
      if (trace.size() != 0)
         cout << s << endl;
      
    }
  };
  static CleanupCheck verifier;
  AutoCounter() : id(count++) {
    verifier.add(this); // Register itself
    std::cout << "created[" << id << "]" 
              << std::endl;
  }
  // Prevent assignment and copy-construction:
  AutoCounter(const AutoCounter&);
  void operator=(const AutoCounter&);
public:
  // You can only create objects with this:
  static AutoCounter* create() { 
    return new AutoCounter();
  }
  ~AutoCounter() {
    std::cout << "destroying[" << id 
              << "]" << std::endl;
    verifier.remove(this);
  }
  // Print both objects and pointers:
  friend std::ostream& operator<<(
    std::ostream& os, const AutoCounter& ac){
    return os << typeid(T).name() << " " << ac.id;
  }
  friend std::ostream& operator<<(
    std::ostream& os, const AutoCounter* ac){
    return os << typeid(T).name() << " " << ac->id;
  }
}; 
#endif // AUTOCOUNTER_H ///:~



class Outer{
   private:
      AutoCounter<Outer> *ac;
   public:
      Outer(){
         ac = AutoCounter<Outer>::create();
      }
      ~Outer(){ delete ac; ac = NULL;}
};

template<> int AutoCounter<Outer>::count = 0;
template<typename> AutoCounter<Outer>::CleanupCheck AutoCounter<Outer>::verifier;



using namespace std;
int main()
{
   
   Outer *o = new Outer;
   Outer *p = new Outer;
   delete o;
//   delete o;  // crashes but displays "attempting to delete twice"

   return 0;
}

/**** TEST.CPP ends on blank line above ****/


-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
MinGW-users mailing list
MinGW-users@xxxxxxxxxxxxxxxxxxxxx

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users