[Mingw-users] [BUG] - member is template<T>: ice in 4.2.1-sjlj (mingw32-2), bad compilation in 3.4.5
- Date: Thu, 20 Dec 2007 12:43:22 +0000 (UTC)
- From: John Brown <johnbrown105@xxxxxxxxxxx>
- Subject: [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