From: dws@mari.co.UK (Don.Sharp)
Subject: Module breaks compiler
Organization: Gnus Not Usenet
Distribution: gnu
Date: Mon, 27 Jul 1992 16:29:12 GMT

I submitted a bug report in respect of the module below which breaks
gcc-2.2.2.

Experimentation has shown that if the typedefs declared inside the class
are moved to BEFORE the class declaration, it compiles okay.

I hope this make it easier to track down the problem.

X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X
// This may look like C code, but it is really -*- C++ -*-

#ifndef _ByteImage_h
#pragma once
#define _ByteImage_h 1

#pragma interface

// extern "C" {
#include	<memory.h>
#include	<sys/types.h>
#include	<unistd.h>
#include	<netinet/in.h>
// }

typedef caddr_t		Address;
typedef unsigned long	Cardinal;

#ifndef NULLP
# define NULLP(x)	((x *) 0)
#endif						// NULLP
#ifndef min
# define min(a, b)	((a) < (b)) ? (a) : (b)
#endif						// min

class ByteImage
{
    typedef struct {
	Cardinal	howmany;
	char	       *where;
	unsigned int	ref_count;
    }	BYTEIMAGEREP;

    typedef struct byteimage{
	BYTEIMAGEREP	b;
	byteimage	*next;
    } BYTEIMAGE;

  public:
    //	Constructor
    ByteImage ();

    // Constructor reading in size bytes from offset on fd
    ByteImage (int fd, Cardinal offset, Cardinal size);

    //	Copy Constructor
    ByteImage (ByteImage &image);

    //	Make an arbitrary contiguous byte sequence into a ByteImage
    ByteImage (Address address, Cardinal length);

    Cardinal size () const;

    //	Make a contiguous byte sequence at destination from this ByteImage
    Cardinal copy (Address destination);

    // Make a contiguous byte sequence of length
    // or size(this) - offset, whichever is less,
    // at destination from this ByteImage starting at offset
    Cardinal copy (Address destination, Cardinal length, Cardinal offset = 0);

    // locate a null starting at offset
    Cardinal find_null (Cardinal offset);

    //	Concatenate ByteImages
    ByteImage &operator += (ByteImage &image);

    //	Concatenate string to ByteImage
    ByteImage &operator += (char *string);

    //	Concatenate Cardinal to ByteImage
    ByteImage &operator += (Cardinal value);

    //	Concatenate long to ByteImage
    ByteImage &operator += (long value);

    //	Destructor
    ~ByteImage ();

  protected:

    //	return self reference
    BYTEIMAGE	   *give_pointer();

    //	update reference count
    void	    ref_step();

  private:

    // append image to the end of the curimage chain
    void append(struct byteimage *curimage, ByteImage &image);

    BYTEIMAGE	   *instance;

};

#endif
X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X


ByteImage.cc:


X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X
#ifndef lint
static char mari_sccsid[] = "@(#)ByteImage.cc	92/07/07 1.8";
#endif /* -lint */

#pragma implementation

#include "ByteImage.h"

void ByteImage::append(struct byteimage *curimage, ByteImage &image)
{
    while (curimage->next != NULLP(BYTEIMAGE))
    {
	curimage = curimage->next;
    }
    image.ref_step();
    curimage->next = image.give_pointer();
}

/*
 *	Constructor
 */

ByteImage::ByteImage ()

{
    instance = new BYTEIMAGE;
    instance->b.where = NULLP(char);
    instance->b.howmany = 0;
    instance->b.ref_count = 1;
    instance->next = NULLP(BYTEIMAGE);
}

/*
 *	create a ByteImage by reading in size bytes from offset on fd
 */
ByteImage::ByteImage (int fd, Cardinal offset, Cardinal size)

{
    instance = new BYTEIMAGE;
    instance->b.where = new char[size];
    (void) lseek(fd, (off_t) offset, SEEK_SET);
    instance->b.howmany = read(fd, instance->b.where, size);
    instance->b.ref_count = 1;
    instance->next = NULLP(BYTEIMAGE);
}

/*
 *	Copy Constructor
 */

ByteImage::ByteImage (ByteImage &image)

{
    image.ref_step();
    instance = image.give_pointer();
}

/*
 *	Make an arbitrary contiguous byte sequence into a ByteImage
 */

ByteImage::ByteImage (Address address, Cardinal length)

{
    instance = new BYTEIMAGE;
    instance->b.where = new char[length];
    memcpy(instance->b.where, address, length);
    instance->b.howmany = length;
    instance->b.ref_count = 1;
    instance->next = NULLP(BYTEIMAGE);
}

Cardinal ByteImage::size () const

{
    Cardinal	    ssize = 0;
    BYTEIMAGE	   *curimage = this->instance;

    do
    {
	ssize += curimage->b.howmany;
    }
    while ((curimage = curimage->next) != (NULLP(BYTEIMAGE)));

    return ssize;
}

/*
 *	Make a contiguous byte sequence at destination from this ByteImage
 */

Cardinal ByteImage::copy (Address destination)

{
    return copy(destination, size(), 0);
}

/*
 *	Make a contiguous byte sequence of length
 *	or size(this) - offset, whichever is less,
 *	at destination from this ByteImage starting at offset
 */

Cardinal ByteImage::copy (Address destination, Cardinal length, Cardinal offset)

{
    Cardinal	    xfer_count = 0;
    int		    l,
		    m,
		    n;
    BYTEIMAGE	   *curimage = instance;
    char	   *source = NULLP(char),
		   *dptr = (char *) destination;

    if ((m = (int) size()) > offset)
    {
	/***
	 * have enough characters for the job so
	 * find the starting point
	 */

	m = min(m - offset, length);			// transfer count
	while (curimage->b.howmany <= offset)
	{
	    offset -= curimage->b.howmany;
	    curimage = curimage->next;
	}

	source = curimage->b.where + offset;
	n = curimage->b.howmany - offset;

	do
	{
	    n = min(n, m);
	    (void) memcpy(dptr, source, n);
	    dptr += n;
	    xfer_count += n;
	    m -= n;
	    if ((curimage = curimage->next) != NULLP(BYTEIMAGE))
	    {
		n = curimage->b.howmany;
		source = curimage->b.where;
	    }
	}
	while (m > 0);
    }

    return xfer_count;
}

/*
 *	Concatenate ByteImages
 */

ByteImage &ByteImage::operator += (ByteImage &image)

{
    append(instance, image);
    return *this;
}

ByteImage &ByteImage::operator += (char *string)

{
    ByteImage	    bt;

    bt = ByteImage((Address) string, (Cardinal) strlen(string) + 1);

    append(instance, bt);

    return *this;
}

ByteImage &ByteImage::operator += (Cardinal value)

{
    ByteImage	    bt;
    Cardinal	    a;

    a = htonl(value);
    bt = ByteImage((Address) &a, (Cardinal) sizeof(Cardinal));

    append(instance, bt);

    return *this;

}

ByteImage &ByteImage::operator += (long value)

{
    ByteImage	    bt;
    Cardinal	    a;

    a = htonl(value);
    bt = ByteImage((Address) &a, (Cardinal) sizeof(long));

    append(instance, bt);

    return *this;

}

struct byteimage * ByteImage::give_pointer()
{
    return instance;
}

void ByteImage::ref_step()
{
    instance->b.ref_count++;
}

Cardinal ByteImage::find_null (Cardinal offset)

{
    BYTEIMAGE	   *curimage = instance;
    Cardinal	    l = offset,
		    orig_offset = offset;
    int		    m,
		    n;
    char	   *source = NULLP(char),
		   *cptr;

    if ((m = (int) size()) > offset)
    {
	m -= offset;

	/***
	 * have enough characters for the job so
	 * find the starting point
	 */

	while (curimage->b.howmany <= offset)
	{
	    offset -= curimage->b.howmany;
	    curimage = curimage->next;
	}

	// have the start
	source = curimage->b.where + offset;
	n = curimage->b.howmany - offset;

	// now find the null
	do
	{
	    n = min(n, m);
	    // MUST walk the memory myself
	    for (cptr = source;
		 (cptr != NULLP(char)) && (*cptr != '\0') &&
		 (cptr < (source + n));
		 cptr++);
	    if (cptr >= (source + n))
	    {
		m -= n;
		l += n;
		if ((curimage = curimage->next) != NULLP(BYTEIMAGE))
		{
		    n = curimage->b.howmany;
		    source = curimage->b.where;
		}
		else
		{
		    l = orig_offset;
		}
	    }
	    else
	    {
		l = l + (cptr - source);
		break;
	    }
	}
	while (m > 0);
    }
    return l;
}

ByteImage::~ByteImage ()

{
    BYTEIMAGE	   *byte,
		   *copy;

    for (byte = instance; byte != NULLP(BYTEIMAGE); byte = copy)
    {
	copy = byte->next;

	if (--byte->b.ref_count == 0)
	{
	    if (byte->b.howmany > 0)
	    {
		delete byte->b.where;
	    }
	    delete byte;
	}
    }
}
X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X
-- 
+----------------------------------------------------------------------+
| Don Sharp                                 Don.Sharp@mari.co.uk       |
| MARI Computer Systems Limited             ========================== |
| Old Town Hall, Gateshead, NE8 1HE, U.K.   ... !uknet!mari!Don.Sharp  |
| Tel +44 91 490 1515, Fax +44 91 490 0013  ========================== |
+----------------------------------------------------------------------+

Newsgroups: gnu.g++.bug