From: ngai@apostle.bellcore.com (John Ngai 21371)
Newsgroups: gnu.g++.bug
Subject: G++ Version 2.3.3 Bug Report
Date: 25 Jan 1993 21:09:44 -0500
Organization: GNUs Not Usenet
Distribution: gnu

Hello:

I like to report a bug I find in using G++-2.3.3, which involves templates.

Here are my source files:
(1) PointerTable.t -- A template definition file.

-----------------------------------------------------------------------------
#ifndef	POINTER_TABLE_T
#include	<stdio.h>

#undef		DFT_HASH_SIZE
#define		DFT_HASH_SIZE	137

/*
  The following defines the generic PointerTable Class for use in all
  subsequent applications. In this case, the stored elements, are always
  pointers to other C++ items. Key is an integral type which admits a 
  hashing function calculation using the operator %. 
*/

template<class Key, class Item> 
class PointerTable
{
  private:

	struct Slot
	{
		Key		key;
		Item	*item;
		Slot	*next;
	};

	int		current_index;
	Slot	*current_slot;
	int		table_size;					// hash table size
	int		population;
	Slot	**head;

	// Compute the internal hash index given key.
	inline int	hash_index(Key key) { return(key % table_size); }

  public:

	inline int size() { return population; }

	// Returns item given key, NULL is not in table.
	Item *search(Key key);

	// Returns table size after inserting item (if not already there).
	int	 insert(Key key, Item *item);

	// Removes item given key, returns removed item, NULL otherwise.
	Item *remove(Key key);

	// The next two methods are for complete table traversal.
	Item *first(); 		// returns first item, NULL if table is empty
	Item *next();		// returns next item in table; NULL when table empty

	// Initialize search table with a hash table size = init_size.
	PointerTable(int init_size); // = DFT_HASH_SIZE);

	// WARNING: Destruction May cause stored pointers to become inaccessible!
	~PointerTable();
};


template<class Key, class Item>
Item *PointerTable<Key, Item>::
search(Key key)
{
	int		index = hash_index(key);
	Slot	*slot = head[index];

	while(slot)
	{	
		if(slot->key==key) break;
		slot = slot->next;
	}

	if(slot) return(slot->item);
	else	return(NULL);
}

template<class Key, class Item>
int	PointerTable<Key, Item>::
insert(Key key, Item *item)
{
	int		index = hash_index(key);
	Slot	*slot = head[index];

	while(slot)
	{	
		if(slot->key==key) break;
		slot = slot->next;
	}
	
	if(slot==NULL)	// a new item, better insert
	{
		slot = new Slot;
		slot->key = key;
		slot->item	= item;
		slot->next = head[index];
		head[index] = slot;
		population++;
	}
	else if(slot->item!=item)
		printf("PointerTable::insert: "
			   "Inserting different items with same key?");

	return(population);
}

template<class Key, class Item>
Item *PointerTable<Key, Item>::
remove(Key key)
{
	int		index = hash_index(key);
	Slot	*prev_slot = NULL, *slot = head[index];
	Item	*item;

	while(slot)
	{	
		if(slot->key==key)
		{
			if(prev_slot)
			{
				prev_slot->next = slot->next;
			}
			else	head[index] = slot->next;
			item = slot->item;
			delete slot;
			population--;
			return(item);
		}			
		prev_slot = slot;
		slot = slot->next;
	}

	// Come here with key NOT found.
	return(NULL);
}

/* 
  For complete traversal of table.
*/
template<class Key, class Item>
Item *PointerTable<Key, Item>::
first()
{
	current_index = table_size;
	current_slot = NULL;
	return(next());
}

template<class Key, class Item>
Item *PointerTable<Key, Item>::
next()
{
	Item	*item;

	while(current_slot==NULL)
	{
		if(current_index==0) return(NULL);		// no more
		current_slot = head[--current_index];
	}

	// Come here with slot found.
	item = current_slot->item;
	current_slot = current_slot->next;
	return(item);
}

template<class Key, class Item>
PointerTable<Key, Item>::
PointerTable(int init_size)
{
	table_size = init_size;
	head = new Slot *[table_size];
}


template<class Key, class Item>
PointerTable<Key, Item>::
~PointerTable()
{
	int		i;
	Slot	*slot;

	for(i=0; i<table_size; i++)
	{
		current_slot = head[i];
		while(current_slot)
		{
			slot = current_slot;
			current_slot = current_slot->next;
			delete slot;
		}
	}
}

#define	POINTER_TABLE_T
#endif
-----------------------------------------------------------------------------

(2) test.c --- A simple test program to use the PointerTable template.

-----------------------------------------------------------------------------
// Let us include the template definition header file.
#include	"PointerTable.t"

// Some random data definition.
struct XXX
{
	int    yyy;
};

main()
{
	PointerTable<int, XXX>	table;
}
-----------------------------------------------------------------------------


Here is the output generated by g++2.3.3 when compiling "test.c" on a
machine called nova:

-----------------------------------------------------------------------------
nova:508 $ g++ -v test.c
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-sunos4.1.2/2.3.3/specs
gcc version 2.3.3
 /usr/local/lib/gcc-lib/sparc-sun-sunos4.1.2/2.3.3/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2
 -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix test
.c /usr/tmp/cca08754.i
GNU CPP version 2.3.3 (sparc)
 /usr/local/lib/gcc-lib/sparc-sun-sunos4.1.2/2.3.3/cc1plus /usr/tmp/cca08754.i -quiet -dumpbase test
.cc -version -o /usr/tmp/cca08754.s
GNU C++ version 2.3.3 (sparc) compiled by GNU C version 2.3.3.
PointerTable.t: In function `int  main ()':
PointerTable.t:57: inconsistent return types for method `PointerTable' in class `PointerTable<int ,X
XX>'
PointerTable.t:57: too few arguments for constructor `PointerTable'
PointerTable.t:57: in base initialization for class `PointerTable<int ,XXX>'
PointerTable.t: In method `PointerTable<int ,XXX>::~PointerTable ()':
PointerTable.t:172: Internal compiler error.
PointerTable.t:172: Please report this to `bug-g++@prep.ai.mit.edu'.
nova:509 $
-----------------------------------------------------------------------------

Hope this helps. Thanks. -- John