[gnu.g++.bug] G++ bug

addie@sirius.trl.oz.au (Ron Addie) (05/02/89)

# To unbundle files into distribution package, on a Unix machine,
# go to the appropriate directory and sh this file
echo bug-report 1>&2
cat >bug-report <<'End of bug-report'
We have recently installed gnu c++ version 1.27.
I have found that one of my programs whichs works with the AT&T c++
compiler on a vax doesn't work with g++ on our Sun 3.
The Sun is operating under Sun OS 4.0, with some of the patches which upgrade
to 4.0.1 installed, but not all. Also, test 13 (from the 1.25 distribution)
does not run successfully. Here is an example of compilation and running of
this test:

argo:~/g++>g++ -o test13 test13.cc intSLList.cc intDLList.cc
argo:~/g++>test13
intSLList a: length() = 0

prepending...90 75 84 81 74 99 52 85 86 47
a: length() = 10
47 86 85 52 99 74 81 84 75 90
appending...8 21 66 51 88 21 66 19 52 29
a: length() = 20
47 86 85 52 99 74 81 84 75 90 8 21 66 51 88 21 66 19 52 29
b = a: length() = 20
47 86 85 52 99 74 81 84 75 90 8 21 66 51 88 21 66 19 52 29
remove_front of first 10 elements:
47 86 85 52 99 74 81 84 75 90
b: length() = 10
8 21 66 51 88 21 66 19 52 29
inserting after sixth element...22
b: length() = 11
8 21 66 51 88 21 22 66 19 52 29
after b.clear() b: length() = 0

Segmentation fault (core dumped)
argo:~/g++>

Here is the details concerning the
files md and tm.h which you requested in the bug report guidelines

argo:/home2/users/liu/gnu/gcc>ls -l md
lrwxrwxrwx  1 liu             7 Apr 24 11:17 md -> m68k.md
argo:/home2/users/liu/gnu/gcc>ls -l tm.h
lrwxrwxrwx  1 liu             9 Apr 24 11:16 tm.h -> tm-sun3.h


Here is the result of running the test with the "-g" option:

argo:~/g++>g++ -g -o test13 *.cc
argo:~/g++>test13
intSLList a: length() = 0

prepending...90 75 84 81 74 99 52 85 86 47
a: length() = 10
47 86 85 52 99 74 81 84 75 90
appending...8 21 66 51 88 21 66 19 52 29
a: length() = 20
47 86 85 52 99 74 81 84 75 90 8 21 66 51 88 21 66 19 52 29
b = a: length() = 20
47 86 85 52 99 74 81 84 75 90 8 21 66 51 88 21 66 19 52 29
remove_front of first 10 elements:
47 86 85 52 99 74 81 84 75 90
b: length() = 10
8 21 66 51 88 21 66 19 52 29
inserting after sixth element...22
b: length() = 11
8 21 66 51 88 21 22 66 19 52 29
after b.clear() b: length() = 0

Segmentation fault (core dumped)

[Seems to be exactly the same]

I have included the source for test13 in this message. (in another file)

Ron Addie
Telecom Australia Research Laboratories.
End of bug-report
echo intDLList.cc 1>&2
cat >intDLList.cc <<'End of intDLList.cc'
// This may look like C code, but it is really -*- C++ -*-
/* 
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of GNU CC.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU CC General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License.   A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  
*/

#include <stream.h>
#include "intDLList.h"

// error handling


void default_intDLList_error_handler(char* msg)
{
  cerr << "Fatal intDLList error. " << msg << "\n";
  exit(1);
}

one_arg_error_handler_t intDLList_error_handler = default_intDLList_error_handler;

one_arg_error_handler_t set_intDLList_error_handler(one_arg_error_handler_t f)
{
  one_arg_error_handler_t old = intDLList_error_handler;
  intDLList_error_handler = f;
  return old;
}

void intDLList::error(const char* msg)
{
  (*intDLList_error_handler)(msg);
}

intDLList::intDLList(intDLList& a)
{
  if (a.h == 0)
    h = 0;
  else
  {
    intDLListNode* p = a.h;
    intDLListNode* t = new intDLListNode(p->hd);
    h = t;
    p = p->fd;
    while (p != a.h)
    {
      intDLListNode* n = new intDLListNode(p->hd);
      t->fd = n;
      n->bk = t;
      t = n;
        p = p->fd;
    }
    t->fd = h;
    h->bk = t;
    return;
  }
}

inline intDLList& intDLList::operator = (intDLList& a)
{
  if (h != a.h)
  {
    clear();
    if (a.h != 0)
    {
      intDLListNode* p = a.h;
      intDLListNode* t = new intDLListNode(p->hd);
      h = t;
      p = p->fd;
      while (p != a.h)
      {
        intDLListNode* n = new intDLListNode(p->hd);
        t->fd = n;
        n->bk = t;
        t = n;
        p = p->fd;
      }
      t->fd = h;
      h->bk = t;
    }
  }
  return *this;
}
void intDLList::clear()
{
  if (h == 0)
    return;

  intDLListNode* p = h->fd;
  h->fd = 0;
  h = 0;

  while (p != 0)
  {
    intDLListNode* nxt = p->fd;
    delete(p);
    p = nxt;
  }
}


void intDLList::prepend(int  item)
{
  intDLListNode* t = new intDLListNode(item);
  if (h == 0)
    t->fd = t->bk = h = t;
  else
  {
    t->fd = h->fd;
    t->bk = h;
    h->fd = t;
    h = t;
  }
}

void intDLList::append(int  item)
{
  intDLListNode* t = new intDLListNode(item);
  if (h == 0)
    t->fd = t->bk = h = t;
  else
  {
    t->fd = h;
    t->bk = h->bk;
    h->bk->fd = t;
    h->bk = t;
  }
}


void intDLListTrav::insert_after(int  item)
{
  if (current == 0)
  {
    L->error("insert_after: null traverser");
    return;
  }
  intDLListNode* t = new intDLListNode(item, current, current->fd);
  current->fd->bk = t;
  current->fd = t;
}

void intDLListTrav::insert_before(int  item)
{
  if (current == 0)
  {
    L->error("insert_before: null traverser");
    return;
  }
  intDLListNode* t = new intDLListNode(item, current->bk, current);
  current->bk->fd = t;
  current->bk = t;
  if (current == L->h)
    L->h = t;
}

void intDLListTrav::del(int dir = 1)
{
  if (current == 0)
  {
    L->error("del: null traverser");
    return;
  }
  intDLListNode* t = current;
  if (t->fd == t)
    current = L->h = 0;
  else
  {
    if (dir < 0)
    {
      if (t == L->h)
        current == 0;
      else
        current = t->bk;
    }
    else
    {
      if (t == L->h->bk)
        current = 0;
      else
        current = t->fd;
    }
    t->bk->fd = t->fd;
    t->fd->bk = t->bk;
    if (t == L->h)
      L->h = t->fd;
  }
  delete t;
}

int intDLList::remove_front()
{
  if (h == 0)
    error("remove_front of empty list");
  intDLListNode* t = h;
  int res = t->hd;
  if (h->fd == h)
    h = 0;
  else
  {
    h->fd->bk = h->bk;
    h->bk->fd = h->fd;
    h = h->fd;
  }
  delete t;
  return res;
}


void intDLList::del_front()
{
  if (h == 0)
    error("del_front of empty list");
  intDLListNode* t = h;
  if (h->fd == h)
    h = 0;
  else
  {
    h->fd->bk = h->bk;
    h->bk->fd = h->fd;
    h = h->fd;
  }
  delete t;
}

int intDLList::remove_rear()
{
  if (h == 0)
    error("remove_rear of empty list");
  intDLListNode* t = h->bk;
  int res = t->hd;
  if (h->fd == h)
    h = 0;
  else
  {
    t->fd->bk = t->bk;
    t->bk->fd = t->fd;
  }
  delete t;
  return res;
}


void intDLList::del_rear()
{
  if (h == 0)
    error("del_rear of empty list");
  intDLListNode* t = h->bk;
  if (h->fd == h)
    h = 0;
  else
  {
    t->fd->bk = t->bk;
    t->bk->fd = t->fd;
  }
  delete t;
}
End of intDLList.cc
echo intSLList.cc 1>&2
cat >intSLList.cc <<'End of intSLList.cc'
// This may look like C code, but it is really -*- C++ -*-
/* 
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of GNU CC.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU CC General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License.   A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  
*/

#include <stream.h>
#include "intSLList.h"

// error handling


void default_intSLList_error_handler(char* msg)
{
  cerr << "Fatal intSLList error. " << msg << "\n";
  exit(1);
}

one_arg_error_handler_t intSLList_error_handler = default_intSLList_error_handler;

one_arg_error_handler_t set_intSLList_error_handler(one_arg_error_handler_t f)
{
  one_arg_error_handler_t old = intSLList_error_handler;
  intSLList_error_handler = f;
  return old;
}

void intSLList::error(const char* msg)
{
  (*intSLList_error_handler)(msg);
}

intSLList::intSLList(intSLList& a)
{
  if (a.last == 0)
    last = 0;
  else
  {
    intSLListNode* p = a.last->tl;
    intSLListNode* h = new intSLListNode(p->hd);
    last = h;
    p = p->tl;
    for (;;)
    {
      intSLListNode* n = new intSLListNode(p->hd);
      last->tl = n;
      last = n;
      if (p == a.last)
      {
        last->tl = h;
        return;
      }
      else
        p = p->tl;
    }
  }
}

inline intSLList& intSLList::operator = (intSLList& a)
{
  if (last == a.last)
    return *this;
  else
  {
    clear();
    if (a.last != 0)
    {
      intSLListNode* p = a.last->tl;
      intSLListNode* h = new intSLListNode(p->hd);
      last = h;
      p = p->tl;
      for (;;)
      {
        intSLListNode* n = new intSLListNode(p->hd);
        last->tl = n;
        last = n;
        if (p == a.last)
        {
          last->tl = h;
          return *this;
        }
        else
          p = p->tl;
      }
    }
  }
}
void intSLList::clear()
{
  if (last == 0)
    return;

  intSLListNode* p = last->tl;
  last->tl = 0;
  last = 0;

  while (p != 0)
  {
    intSLListNode* nxt = p->tl;
    delete(p);
    p = nxt;
  }
}


void intSLList::prepend(int  item)
{
  intSLListNode* t = new intSLListNode(item);
  if (last == 0)
    t->tl = last = t;
  else
  {
    t->tl = last->tl;
    last->tl = t;
  }
}

void intSLList::append(int  item)
{
  intSLListNode* t = new intSLListNode(item);
  if (last == 0)
    t->tl = last = t;
  else
  {
    t->tl = last->tl;
    last = last->tl = t;
  }
}


void intSLListTrav::insert_after(int  item)
{
  intSLListNode* t = new intSLListNode(item);
  if (L->last == 0)
    t->tl = L->last = current = t;
  else if (current == 0)
  {
    t->tl = L->last->tl;
    L->last = t;
  }
  else if (L->last == current)
  {
    t->tl = current->tl;
    current->tl = L->last = t;
  }
  else
  {
    t->tl = current->tl;
    current->tl = t;
  }
}


int intSLList::remove_front()
{
  if (last == 0)
    error("remove_front of empty list");
  intSLListNode* t = last->tl;
  int res = t->hd;
  if (t == last)
    last = 0;
  else
    last->tl = t->tl;
  delete t;
  return res;
}

int intSLList::remove_front(int& x)
{
  if (last == 0)
    return 0;
  else
  {
    intSLListNode* t = last->tl;
    x = t->hd;
    if (t == last)
      last = 0;
    else
      last->tl = t->tl;
    delete t;
    return 1;
  }
}

void intSLList::del_front()
{
  if (last == 0)
    error("del_front of empty list");
  intSLListNode* t = last->tl;
  if (t == last)
    last = 0;
  else
    last->tl = t->tl;
  delete t;
}

End of intSLList.cc
echo test13.cc 1>&2
cat >test13.cc <<'End of test13.cc'
/*
 test/demo of linked structures
*/

#include <stream.h>
#include "intSLList.h"
#include "intDLList.h"

void printint(int x)
{
  cout << x << " ";
}


void printlist(intSLList& l)
{
  for (intSLListTrav p(l); p; p.advance())
    cout << p.get() << " ";
  cout << "\n";
}

void printDlist(intDLList& l)
{
  for (intDLListTrav p(l); p; p.advance())
    cout << p.get() << " ";
  cout << "\n";
}

main()
{
  int i, x;
  intSLList a;
  cout << "intSLList a: length() = " << a.length() << "\n"; printlist(a);
  cout << "prepending...";
  for (i = 0; i < 10; ++i)
  {
    x = rand() % 100;
    cout << x << " ";
    a.prepend(x);
  }
  cout << "\n";
  cout << "a: length() = " << a.length() << "\n"; printlist(a);
  cout << "appending...";
  for (i = 0; i < 10; ++i)
  {
    x = rand() % 100;
    cout << x << " ";
    a.append(x);
  }
  cout << "\n";
  cout << "a: length() = " << a.length() << "\n"; printlist(a);
  intSLList b = a;
  cout << "b = a: length() = " << b.length() << "\n"; printlist(b);
  cout << "remove_front of first 10 elements:\n";
  for (i = 0; i < 10; ++i) cout << b.remove_front() << " ";
  cout << "\n";
  cout << "b: length() = " << b.length() << "\n"; printlist(b);

  cout << "inserting after sixth element...";
  intSLListTrav bp(b);
  for (i = 0; i < 5; ++i) bp.advance();
  x = rand() % 100;
  cout << x << " ";
  bp.insert_after(x);
  cout << "\n";
  cout << "b: length() = " << b.length() << "\n"; printlist(b);
  b.clear();
  cout << "after b.clear() ";
  cout << "b: length() = " << b.length() << "\n"; printlist(b);


  intSLStack s;
  cout << "pushing all of a onto stack s...";
  for (intSLListTrav ap = a; ap; ap.advance()) s.push(ap.get());
  cout << "popping all of s:\n";
  while (s) cout << s.pop() << " ";
  cout << "\n";

  intSLQueue q;
  cout << "enqueueing all of a onto queue q...";
  for (ap = a; ap; ap.advance()) q.enq(ap.get());
  cout << "dequeueing all of q:\n";
  while (q) cout << q.deq() << " ";
  cout << "\n";

  intDLList y;
  cout << "intDLList y: length() = " << y.length() << "\n"; printDlist(y);
  cout << "prepending...";
  for (i = 0; i < 10; ++i)
  {
    x = rand() % 100;
    cout << x << " ";
    y.prepend(x);
  }
  cout << "\n";
  cout << "y: length() = " << y.length() << "\n"; printDlist(y);
  cout << "appending...";
  for (i = 0; i < 10; ++i)
  {
    x = rand() % 100;
    cout << x << " ";
    y.append(x);
  }
  cout << "\n";
  cout << "y: length() = " << y.length() << "\n"; printDlist(y);
  intDLList z = y;
  cout << "z = y: length() = " << z.length() << "\n"; printDlist(z);
  cout << "remove_front of first 10 elements:\n";
  for (i = 0; i < 10; ++i) cout << z.remove_front() << " ";
  cout << "\n";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);

  cout << "remove_rear of last 5 elements:\n";
  for (i = 0; i < 5; ++i) cout << z.remove_rear() << " ";
  cout << "\n";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);

  cout << "inserting before alternate elements...";
  for (intDLListTrav zp(z); zp; zp.advance())
  {
    x = rand() % 100;
    cout << x << " ";
    zp.insert_before(x);
  }
  cout << "\n";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);

  cout << "inserting after sixth element...";
  zp.reset(z);
  for (i = 0; i < 5; ++i) zp.advance();
  x = rand() % 100;
  cout << x << " ";
  zp.insert_after(x);
  cout << "\n";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);

  cout << "deleting alternate elements of z...";
  for (zp.reset(); zp; zp.advance())
  {
    cout << zp.get() << " ";
    zp.del();
  }
  cout << "\n";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);
  
  cout << "z in reverse order via traverser:\n";
  for (zp.reset(-1); zp; zp.advance(-1))
    cout << zp.get() << " ";
  cout << "\n";
  z.clear();
  cout << "after z.clear() ";
  cout << "z: length() = " << z.length() << "\n"; printDlist(z);

  cout << "\nEnd of test\n";
}
End of test13.cc

[part 2 of this message has been sent separately on account of length restrictions
on e-mail; it contains the .h files]

addie@sirius.trl.oz.au (Ron Addie) (05/02/89)

# This is part 2 of a two part message.
#
# To unbundle files into distribution package, on a Unix machine,
# go to the appropriate directory and sh this file
echo intDLList.h 1>&2
cat >intDLList.h <<'End of intDLList.h'
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of GNU CC.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU CC General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License.   A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.
*/


#ifndef _intDLList_h
#define _intDLList_h 1

#ifndef _intDLListNode_h
#define _intDLListNode_h 1

struct intDLListNode
{
  intDLListNode*         bk;
  intDLListNode*         fd;
  int                    hd;
                         intDLListNode();
                         intDLListNode(int  h,
                                       intDLListNode* p = 0,
                                       intDLListNode* n = 0);
                         ~intDLListNode();
};

inline intDLListNode::intDLListNode() {}

inline intDLListNode::intDLListNode(int  h, intDLListNode* p = 0,
                                    intDLListNode* n = 0)
{
  hd = h;
  bk = p;
  fd = n;
}

inline intDLListNode::~intDLListNode() {}

typedef intDLListNode* intDLListNodePtr;

#endif

class intDLListTrav;

class intDLList
{
  friend class          intDLListTrav;

  intDLListNode*        h;

public:
                        intDLList();
                        intDLList(intDLList& a);
                        ~intDLList();

  intDLList&            operator = (intDLList& a);

  int                   null();
  int                   empty();
  int                   valid();
  const void*           operator void* ();
  int                   operator ! ();
  int                   length();
  void                  clear();

  void                  prepend(int  item);
  void                  append(int  item);

  int&                  front();
  int                   remove_front();
  void                  del_front();

  int&                  rear();
  int                   remove_rear();
  void                  del_rear();

  void                  error(const char* msg);
};

class intDLListTrav
{
  friend class          intDLList;

  intDLList*            L;
  intDLListNode*        current;
public:
                        intDLListTrav(intDLList& l, int dir = 1);
                        ~intDLListTrav();

  int                   null();
  int                   valid();
  const void*           operator void* ();
  int                   operator ! ();

  void                  advance(int dir = 1);
  int&                  get();
  void                  reset(int dir = 1);
  void                  reset(intDLList& l, int dir = 1);
  void                  insert_after(int item);
  void                  insert_before(int item);
  void                  del(int dir = 1);
};


extern void default_intDLList_error_handler(char*);
extern one_arg_error_handler_t intDLList_error_handler;

extern one_arg_error_handler_t
        set_intDLList_error_handler(one_arg_error_handler_t f);


inline intDLList::~intDLList()
{
  clear();
}

inline intDLList::intDLList()
{
  h = 0;
}


inline int intDLList::null()
{
  return h == 0;
}

inline int intDLList::empty()
{
  return h == 0;
}

inline int intDLList::valid()
{
  return h != 0;
}

inline const void* intDLList::operator void* ()
{
  return (h == 0)? 0 : this;
}

inline int intDLList::operator ! ()
{
  return h == 0;
}

inline int intDLList::length()
{
  if (h == 0)
    return 0;
  else
  {
    int l = 1;
    for (intDLListNode* p = h->fd; p != h; p = p->fd) ++l;
    return l;
  }
}


inline intDLListTrav::intDLListTrav(intDLList& a, int dir = 1)
{
  L = &a;
  if ((current = L->h) != 0 && dir < 0) current = current->bk;
}

inline void intDLListTrav::reset(intDLList& a, int dir = 1)
{
  L = &a;
  if ((current = L->h) != 0 && dir < 0) current = current->bk;
}

inline void  intDLListTrav::reset(int dir = 1)
{
  if ((current = L->h) != 0 && dir < 0) current = current->bk;
}

inline intDLListTrav::~intDLListTrav() {}

inline int intDLListTrav::null()
{
  return current == 0;
}

inline int intDLListTrav::valid()
{
  return current != 0;
}

inline const void* intDLListTrav::operator void* ()
{
  return (current == 0)? 0 : this;
}

inline int intDLListTrav::operator ! ()
{
  return (current == 0);
}

inline void intDLListTrav::advance(int dir = 1)
{
  if (current != 0)
  {
    if (dir < 0)
      current = (current == L->h)? 0 : current->bk;
    else
      current = (current == L->h->bk)? 0 : current->fd;
  }
}

inline int& intDLListTrav::get()
{
  if (current == 0)
    (*intDLList_error_handler)("get from null traverser");
  return current->hd;
}


inline int& intDLList::front()
{
  if (h == 0)
    error("front: empty list");
  return h->hd;
}

inline int& intDLList::rear()
{
  if (h == 0)
    error("rear: empty list");
  return h->bk->hd;
}




#endif
End of intDLList.h
echo intSLList.h 1>&2
cat >intSLList.h <<'End of intSLList.h'
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of GNU CC.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU CC General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License.   A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.
*/


#ifndef _intSLList_h
#define _intSLList_h 1

#ifndef _intSLListNode_h
#define _intSLListNode_h 1

struct intSLListNode
{
  intSLListNode*         tl;
  int                    hd;
                         intSLListNode();
                         intSLListNode(int  h, intSLListNode* t = 0);
                         ~intSLListNode();
};

inline intSLListNode::intSLListNode() {}

inline intSLListNode::intSLListNode(int  h, intSLListNode* t = 0)
{
  hd = h;
  tl = t;
}

inline intSLListNode::~intSLListNode() {}

typedef intSLListNode* intSLListNodePtr;

#endif

class intSLListTrav;

class intSLList
{
  friend class          intSLListTrav;

  intSLListNode*        last;

public:
                        intSLList();
                        intSLList(intSLList& a);
                        ~intSLList();

  intSLList&            operator = (intSLList& a);

  int                   null();
  int                   empty();
  int                   valid();
  const void*           operator void* ();
  int                   operator ! ();
  int                   length();
  void                  clear();

  void                  prepend(int  item);
  void                  append(int  item);

  int&                  front();
  int&                  rear();
  int                   remove_front();
  int                   remove_front(int& item);
  void                  del_front();

  void                  error(const char* msg);
};

class intSLListTrav
{
  friend class          intSLList;

  intSLList*            L;
  intSLListNode*        current;
public:
                        intSLListTrav(intSLList& l);
                        ~intSLListTrav();

  int                   null();
  int                   valid();
  const void*           operator void* ();
  int                   operator ! ();

  void                  advance();
  int&                  get();
  void                  reset();
  void                  reset(intSLList& l);
  void                  insert_after(int item);
};

class intSLStack : private intSLList
{
public:
  intSLList::null();
  intSLList::empty();
  intSLList::clear();
  intSLList::length();
  intSLList::operator ! ();
  intSLList::operator void*();
  intSLList::error(const char* msg);

                        intSLStack();
                        intSLStack(intSLStack& a);
                        ~intSLStack();
  intSLStack&           operator = (intSLStack& a);

  void                  push(int  item);
  int                   pop();
  int                   pop(int& x);
  void                  del_top();
  int&                  top();
};

class intSLQueue: private intSLList
{
public:
  intSLList::null();
  intSLList::empty();
  intSLList::clear();
  intSLList::length();
  intSLList::operator ! ();
  intSLList::operator void*();
  intSLList::error(const char* msg);
  intSLList::front();
  intSLList::rear();
  intSLList::del_front();

                        intSLQueue();
                        intSLQueue(intSLQueue& a);
                        ~intSLQueue();
  intSLQueue&           operator = (intSLQueue& a);

  void                  enq(int  item);
  int                   deq();
  int                   deq(int& x);

};


extern void default_intSLList_error_handler(char*);
extern one_arg_error_handler_t intSLList_error_handler;

extern one_arg_error_handler_t
        set_intSLList_error_handler(one_arg_error_handler_t f);


inline intSLList::~intSLList()
{
  clear();
}

inline intSLList::intSLList()
{
  last = 0;
}


inline int intSLList::null()
{
  return last == 0;
}

inline int intSLList::empty()
{
  return last == 0;
}

inline int intSLList::valid()
{
  return last != 0;
}

inline const void* intSLList::operator void* ()
{
  return (last == 0)? 0 : this;
}

inline int intSLList::operator ! ()
{
  return last == 0;
}

inline int intSLList::length()
{
  if (last == 0)
    return 0;
  else
  {
    int l = 1;
    for (intSLListNode* p = last->tl; p != last; p = p->tl) ++l;
    return l;
  }
}


inline intSLListTrav::intSLListTrav(intSLList& a)
{
  L = &a;
  if (a.last == 0)
    current =  0;
  else
    current = a.last->tl;
}

inline void intSLListTrav::reset()
{
  if (L->last == 0) current = 0; else current = L->last->tl;
}

inline void intSLListTrav::reset(intSLList& a)
{
  L = &a;
  if (a.last == 0)
    current =  0;
  else
    current = a.last->tl;
}


inline intSLListTrav::~intSLListTrav() {}

inline int intSLListTrav::null()
{
  return current == 0;
}

inline int intSLListTrav::valid()
{
  return current != 0;
}

inline const void* intSLListTrav::operator void* ()
{
  return (current == 0)? 0 : this;
}

inline int intSLListTrav::operator ! ()
{
  return (current == 0);
}

inline void intSLListTrav::advance()
{
  if (current != 0)
  {
    current = (current == L->last)? 0 : current->tl;
  }
}

inline int& intSLListTrav::get()
{
  if (current == 0)
    (*intSLList_error_handler)("get from null traverser");
  return current->hd;
}


inline int& intSLList::front()
{
  if (last == 0)
    error("front: empty list");
  return last->tl->hd;
}

inline int& intSLList::rear()
{
  if (last == 0)
    error("rear: empty list");
  return last->hd;
}


inline intSLStack::intSLStack() {}
inline intSLStack::intSLStack(intSLStack& a) : (a) {}
inline intSLStack::~intSLStack() {}
inline intSLStack&  intSLStack::operator = (intSLStack& a)
{
  intSLList::operator = (a); return *this;
}

inline void  intSLStack::push(int  item)
{
  intSLList::prepend(item);
}

inline void intSLStack::del_top()
{
  intSLList::del_front();
}

inline int& intSLStack::top()
{
  return intSLList::front();
}

inline int intSLStack::pop()
{
  return intSLList::remove_front();
}

inline int intSLStack::pop(int& x)
{
  return intSLList::remove_front(x);
}

inline intSLQueue::intSLQueue() {}
inline intSLQueue::intSLQueue(intSLQueue& a) : (a) {}
inline intSLQueue::~intSLQueue() {}
inline intSLQueue&  intSLQueue::operator = (intSLQueue& a)
{
  intSLList::operator = (a); return *this;
}

inline void  intSLQueue::enq(int  item)
{
  intSLList::append(item);
}

inline int intSLQueue::deq()
{
  return intSLList::remove_front();
}

inline int intSLQueue::deq(int& x)
{
  return intSLList::remove_front(x);
}


#endif
End of intSLList.h

sdm@CS.BROWN.EDU (05/20/89)

Note the fatal signal received by c++ in the following transcript:

    % g++ -g -v -c tester.cc -o tester.o
    g++ version 1.34.2
     /cs/lib/gnu/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ tester.cc /tmp/cca22554.cpp
    GNU CPP version 1.35
     /cs/lib/gnu/gcc-c++ /tmp/cca22554.cpp -quiet -dumpbase tester.cc -noreg -version -G -o /tmp/cca22554.s
    GNU C++ version 1.34.2 (sparc) compiled by GNU C version 1.34.
    Program c++ got fatal signal 6.

g++ -E tester.cc produces the following:

    # 1 "tester.cc"
    class base
    {
      int x;
    };

    class derived: public base
    {
      int y;
    };


    main()
    {
      base b;
      derived d;
      base *bp;
      derived *dp;

      bp = dp;
      bp = (base *) dp;

      b = d;
    }

This is running on a sun4 running SunOS Release 4.0.  The same source
compiles without problem on a sun3 running the same version of g++ and GNU
CPP. 

Since I'm not in charge of installing the compiler, I'm not sure what the
names of the files 'tm.h' and 'md' were during installation, but I did poke
around in the installation directory, and files with those names exist
there.  If you can't do anything without the names of those files, let me
know, and I'll find out what was used during installation.

Scott Meyers
sdm@cs.brown.edu

sdm@CS.BROWN.EDU (05/27/89)

Consider the following program:

    #include <stream.h>

    class C { public: int x = 5; };

    main(){
      C foo;
      cout << foo.x << "\n";
     }

This compiles without warnings or errors under g++ 1.34.2 on a sun3 or sun4
running SunOS Release 4.0.  When I run the program, however, the value
printed out is not 5.  On the sun4 it's 0, and on the sun3 it's 251656748.
I'd prefer to see either a compiler error or correct execution :-).

Since I'm not in charge of installing the compiler, I'm not sure what the
names of the files 'tm.h' and 'md' were during installation, but I did poke
around in the installation directory, and files with those names exist
there.  If you can't do anything without the names of those files, let me
know, and I'll find out what was used during installation.

Scott Meyers
sdm@cs.brown.edu

schmidt@ics.uci.edu (Doug Schmidt) (05/27/89)

In article <8905261837.AA02121@sundry.cs.brown.edu> sdm@CS.BROWN.EDU writes:
++ Consider the following program:
++ 
++     #include <stream.h>
++ 
++     class C { public: int x = 5; };
++ 
++     main(){
++       C foo;
++       cout << foo.x << "\n";
++      }
++ 
++ This compiles without warnings or errors under g++ 1.34.2 on a sun3 or sun4
++ running SunOS Release 4.0.  When I run the program, however, the value
++ printed out is not 5.  On the sun4 it's 0, and on the sun3 it's 251656748.
++ I'd prefer to see either a compiler error or correct execution :-).

This appears to be fixed in version 1.35.

Doug
--
On a clear day, under blue skies, there is no need to seek.
And asking about Buddha                +------------------------+
Is like proclaiming innocence,         | schmidt@ics.uci.edu    |
With loot in your pocket.              | office: (714) 856-4043 |

gam%ranger@LANL.GOV (Graham Mark) (06/06/89)

I've run into something that appears to be a compiler bug.  Here are
some facts:

"g++ -v" returns:
GNU C++ compiler driver, version 1.18.2
/usr/local/lib/gcc-ld++ -C /usr/local/lib/gcc-crt0+.o -lg++
/usr/local/lib/gcc-gnulib+ -lc

The source goes through the preprocessor OK.  I'll append the output
resulting from "g++ -E".

After trying to compile my source with 
"g++ -g -c dlink.cc" 
or with 
"g++ -c dlink.cc"
I get back
g++: Program c++ got fatal signal 6.

I'm using a Sun 3/50 running Sun OS 4.0.1.  The person who installed the
compiler said to tell you that the tm.h and md files are for Sun 3.

Please let me know if you need more information.

Graham Mark

-------------------------------------------------------------------

# 1 "dlink.cc"
 

 
 




 

# 1 "/usr/local/lib/gcc-include/stream.h"
 
 
























# 1 "/usr/local/lib/gcc-include/File.h"
 
 
























# 1 "/usr/local/lib/gcc-include/stdio.h"
 
 





















 















extern  struct  _iobuf {
    int      _cnt;
    char*    _ptr;
    char*    _base;

    int     _bufsiz;
    short   _flag;



    char    _file;
} _iob[];




































extern int    _doprnt(const char*, void*,     struct _iobuf *);
extern int    _doscan(    struct _iobuf *, const char*, void*);
extern int    _filbuf(    struct _iobuf *);
extern int    _flsbuf(unsigned,     struct _iobuf *);
extern int    fclose(    struct _iobuf *);
extern     struct _iobuf *  fdopen(int, const char*);
extern int    fflush(    struct _iobuf *);
extern int    fgetc(    struct _iobuf *);
extern char*  fgets(char*, int,     struct _iobuf  *);
extern     struct _iobuf *  fopen(const char*, const char*);
extern int    fprintf(    struct _iobuf *, const char* ...);
extern int    fputc(int,     struct _iobuf *);
extern void   fputs(const char*,     struct _iobuf *);
extern int    fread(void*, int, int,     struct _iobuf *);
extern     struct _iobuf *  freopen(const char*, const char*,     struct _iobuf *);
extern int    fscanf(    struct _iobuf *, const char* ...);
extern int    fseek(    struct _iobuf *, long, int);
extern long   ftell(    struct _iobuf  *);
extern int    fwrite(const void*, int, int,     struct _iobuf *);
extern char*  gets(char*);
extern int    getw(    struct _iobuf *);
extern int    pclose(    struct _iobuf *);
extern     struct _iobuf *  popen(const char*, const char*);
extern int    printf(const char* ...);
extern void   puts(const char*);
extern int    putw(int,     struct _iobuf *);
extern int    scanf(const char* ...);
extern void   setbuf(    struct _iobuf *, char*);
extern void   setbuffer(    struct _iobuf *, char*, int);
extern void   setlinebuf(    struct _iobuf *);
extern void   setvbuf(    struct _iobuf *, char*, int, int);
extern int    sprintf(char*, const char* ...);
extern int    sscanf(char*, const char* ...);
extern     struct _iobuf *  tmpfile();
extern int    ungetc(int,     struct _iobuf *);
extern int    vfprintf(    struct _iobuf *, const char*, void* ap);
extern int    vprintf(const char*, void* ap);
extern int    vsprintf(char*, const char*, void* ap);


# 27 "/usr/local/lib/gcc-include/File.h"



enum io_mode                     
{
  io_readonly   = 0,            
  io_writeonly  = 1,
  io_readwrite  = 2, 
  io_appendonly = 3,
  io_append     = 4,             
};

enum access_mode                 
{
  a_createonly  = 0,             
  a_create      = 1,             
  a_useonly     = 2,             
  a_use         = 3,             
};


enum state_value                 
{ 
  _good         = 0,             
  _eof          =    00020 ,        
  _fail         =    00040 ,        
  _bad          = 0400000        
};

class String;

class File
{

      struct _iobuf * fp;                        
  char* nm;                        
  int   stat;                      
  char  opened;                    
  char  perrors;                   

public:

 

  File& initialize() {fp=0; nm=0; opened=0; stat=0; perrors=1; return(*this);}

  File& open(const char* filename, io_mode m, access_mode a);
  File& open(const char* filename, const char* m);
  File& open(int  filedesc, io_mode m);
  File& open(    struct _iobuf * fileptr);

  File& close();
  File& remove();                    


 

  File()                            { initialize(); }

  File(const char* filename, io_mode m, access_mode a)   
                                    { initialize(); open(filename, m, a); }
  File(const char* filename, const char* m)   
                                    { initialize(); open(filename, m); }
  File(int filedesc, io_mode m)     { initialize(); open(filedesc, m); }
  File(    struct _iobuf * fileptr)               { initialize(); open(fileptr); }

  ~File();


 

  int   filedesc()                  { return(fp->_file); }
  int   is_open()                   { return(opened); }

  char* name()                      { return(nm); }
  void  setname(const char* newname);


 

  int   rdstate()                   { return((fp==0) ? _bad : (opened) ? 
                                             fp->_flag&(_eof|_fail) :
                                             _bad|(fp->_flag&(_eof|_fail))); }

  void* operator void*()            { return((fp==0||(fp->_flag&_fail))?
                                       0 : this); }

  int   eof()                       { return(rdstate() &  _eof); }
  int   fail()                      { return(rdstate() &  _fail); }
  int   bad()                       { return(rdstate() &  _bad); }
  int   good()                      { return(rdstate() == _good); }

  int   iocount()                   { return(stat); }
  int   readable()                  { return(fp->_flag &(  00001 |    00400 )); }
  int   writable()                  { return(fp->_flag &(   00002 |    00400 )); }

  void  verbose()                   { perrors = 1; }
  void  quiet()                     { perrors = 0; }


 

  File& clear()                     { if (fp!=0) fp->_flag &= ~(_fail);
                                      return(*this); }
  File& error();                     
  File& failif(int cond)            { return( (cond) ? error(): *this); }


 


  File& get(char& c) { if (--fp->_cnt >= 0) { c = *fp->_ptr++; return(*this); }
                        c = ::_filbuf(fp); return(failif(fp->_flag & _eof)); }
  File& put(char  c) { if (--fp->_cnt >= 0) *fp->_ptr++ = c; 
                        else ::_flsbuf((unsigned)c, fp);   return(*this); }

  File& unget(char c)               { return(failif(::ungetc(c, fp)==     (-1) ));} 
  File& putback(char c)             { return(File::unget(c)); }

 

  File& put(const char* s)          { ::fputs(s, fp); return(*this); }
  File& get    (char* s, int n, char terminator = '\n');  
  File& getline(char* s, int n, char terminator = '\n');  


 

  File& put(String& x);
  File& get    (String& x, int n, char terminator = '\n');
  File& getline(String& x, int n, char terminator = '\n');

 

  File& read(void* x, int sz, int n)  { return(failif((stat = 
                                        ::fread(x, sz, n, fp)) != n)); } 
  File& write(void* x, int sz, int n) { return(failif((stat = 
                                        ::fwrite(x, sz, n, fp)) != n)); }

 

  File& form(const char* fmt, ...);
  File& scan(const char* fmt, ...);


 

  File& flush()                     { return(failif(::fflush(fp)==     (-1) )); }
  File& seek(long pos, int seek_mode = 0)  
                                    { return(failif
                                       (::fseek(fp, pos, seek_mode) < 0)); }
  int   tell()                      { return(stat = ::ftell(fp)); }

  File& setbuf(int buffer_kind);     
  File& raw()                       { return(File::setbuf(   00004 )); }
  File& setbuf(int size, char* buf);

};

 

char* hex(long x, int width = 0);
char* oct(long x, int width = 0);
char* dec(long x, int width = 0);
char* form(const char* fmt ...);


# 27 "/usr/local/lib/gcc-include/stream.h"


class whitespace                 
{                                
  char filler;                     
};

class ostream: File
{

public:
  File::open;      File::close;     File::initialize;
  File::remove;    File::filedesc;  File::is_open;
  File::raw;       File::quiet;     File::verbose;
  File::iocount;   File::error;     File::name;
  File::setname;   File::rdstate;
  File::eof;       File::fail;      File::bad;
  File::good;      File::clear;     File::failif;
  File::setbuf;    File::writable;  File::readable;
  File::put;       File::form;      File::flush;

  ostream() {}
  ostream(const char* filename, io_mode m, access_mode a) :(filename, m, a) {}
  ostream(const char* filename, const char* m)            :(filename, m) {}
  ostream(int filedesc, io_mode m)                        :(filedesc, m) {}
  ostream(    struct _iobuf * fileptr)                                  :(fileptr) {}
  ~ostream() {}

  void* ostream::operator void*()    { return((fail())?0:this); }

  ostream& operator<<(char   c)      { put(c);              return(*this);}
  ostream& operator<<(short  n)      { form("%d",(int)n);   return(*this);}
  ostream& operator<<(int    n)      { form("%d",n);        return(*this);}
  ostream& operator<<(long   n)      { form("%ld",n);       return(*this);}
  ostream& operator<<(float  n)      { form("%g",(double)n);return(*this);}
  ostream& operator<<(double n)      { form("%g",n);        return(*this);}
  ostream& operator<<(const char* s) { put(s);              return(*this);}
};


class istream: File
{
public:
  File::open;      File::close;     File::initialize;
  File::remove;    File::filedesc;  File::is_open;
  File::raw;       File::quiet;     File::verbose;
  File::iocount;   File::error;     File::name;
  File::setname;   File::rdstate;
  File::eof;       File::fail;      File::bad;
  File::good;      File::clear;     File::failif;
  File::setbuf;    File::writable;  File::readable;
  File::get;       File::unget;     File::scan;
  File::putback;


  istream() {}
  istream(const char* filename, io_mode m, access_mode a) :(filename, m, a) {}
  istream(const char* filename, const char* m)            :(filename, m) {}
  istream(int filedesc, io_mode m)                        :(filedesc, m) {}
  istream(    struct _iobuf * fileptr)                                  :(fileptr) {}
  ~istream() {}

  void*    operator void*()      { return((fail())?0:this); }

  istream& operator>>(char&   c) { get(c);          return(*this); }
  istream& operator>>(short&  n) { scan("%hd", &n); return(*this); }
  istream& operator>>(int&    n) { scan("%d",  &n); return(*this); }
  istream& operator>>(long&   n) { scan("%ld", &n); return(*this); }
  istream& operator>>(float&  n) { scan("%f",  &n); return(*this); }
  istream& operator>>(double& n) { scan("%lf", &n); return(*this); }
  istream& operator>>(char*   s) { scan("%s",   s); return(*this); }
  istream& operator>>(whitespace& w);
};


 

extern istream  cin;              
extern ostream  cout;             
extern ostream  cerr;             

extern whitespace WS;             


# 11 "dlink.cc"

# 1 "dlink.h"
 

 
 




 




# 1 "Pix.h"



typedef void* Pix;

# 14 "dlink.h"


class	dLink;
typedef	dLink* dLinkPtr;
typedef	void* vPtr;

class	dLink
{
	friend	class dList;
	friend	class dList_iterator;
	
	dLinkPtr nx;			 
	dLinkPtr pr;			 
	vPtr	data;			 

	dLink( vPtr a, dLinkPtr n, dLinkPtr p );
};

inline	dLink::dLink( vPtr a, dLinkPtr n = 0, dLinkPtr p = 0 )
{
	data = a; 			 
	nx = n; pr = p;
}

 

class	dList
{
	friend	class dList_iterator;

	dLinkPtr last;			 

	public:

		dList();
		dList( vPtr a );
		dList( dList& x );
		~dList();

	dList&	operator = ( dList& x );
	vPtr	operator () ( Pix p );
	int	empty();
	int	length();
	void	clear();
	Pix	append( vPtr a );
	Pix	prepend( vPtr a );
	void	join( dList& x );
	vPtr	head();
	vPtr	get_head();
	void	cut_head();
	vPtr	foot();
	vPtr	get_foot();
	void	cut_foot();
	Pix	first();
	Pix	last();
	void	next( Pix& p );
	void	prev( Pix& p );
	int	owns( Pix p );
	Pix	put_after( Pix p, vPtr a );
	Pix	put_before( Pix p, vPtr a );
	void	cut( Pix& p, int dir = 1 );

	void	error( char *msg );
	int	ok();
};

inline	dList::dList()		{ last =     0 ; }

inline	dList::dList( vPtr a )	
{ 
	last = new dLink( a,     0 ,     0  );
	last->nx = last->pr = last;
}

inline	dList::~dList()		{ clear(); }

inline	int dList::empty()	{ return( last ==     0  ); }

inline	int dList::length()
{
	for (int n = 0, dLinkPtr t = last ; t != last && t !=     0  ; )
		{ ++n; t= t->nx; }
	return( n );
}

inline	void dList::next( Pix& p )
{
	p = (p == 0 || p == last) ? 0 : Pix(((dListPtr)p)->nx);
}

inline	void dList::prev( Pix& p )
{
	p = (p == 0 || p == last->nx) ? 0 : Pix(((dListPtr)p)->pr);
}

inline	Pix dList::first()	
{ 
	return( (last ==     0 ) ? 0 : Pix( last->nx ) ); 
}

inline	Pix dList::last()	{ return( Pix( last ) ); }

inline	vPtr dList::head()
{
	if (last ==     0 ) error( "front: empty list" );
	return( last->nx.data );
}

inline	vPtr dList::foot()
{
	if (last ==     0 ) error( "foot: empty list" );
	return( last.data );
}


 
 
# 12 "dlink.cc"


void	dList:error( char *msg )
{
	cerror << "\nll: " << msg << "\n";
}

dList::dList( dList& x )		 
{
	if (x.last ==     0 )
		last =     0 ;		 
	else
	{
		dLinkPtr p = x.nx
		dLinkPtr t = new dLink( p->data );
		 
		last = t;
		p = p->fd;
		while (p != x.nx)
		{
			dLinkPtr n = new dLink( p->data );
			 
			t->nx = n;
			n->pr = t;
			p = p->nx;
		}
		t->nx = last;
		last->bk = t;
		last = t;
	}
}

void	dList::clear()
{
	if (last ==     0 )
		return;
	if ((dLinkPtr q = last.nx) ==     0 )
	{
		error( "clear: last.nx is NULL" );
		exit( 1 );
	}

	dLinkPtr p = last;
	last =     0 ;
	while (p != q)
	{
		dLinkPtr r = p;
		p = p->pr;
		r->nx = r->pr =     0 ;
		delete( r );
	}
	p->nx = p->pr =     0 ;
	delete( p );
}

Pix	dList::append( vPtr a )
{
	if (last)
	{
		dLinkPtr t = new dLinkPtr( a, last->nx, last );
		last->nx = (last->nx).pr = t;
		last = t;		 
		
	}
	else
	{
		dLinkPtr t = new dLinkPtr( a );
		last = t->nx = t->pr = t;
	}
	return( Pix( t ) );
}

Pix	dList::prepend( vPtr a )
{
	if (last)
	{
		dLinkPtr t = new dLinkPtr( a, last->nx, last );
		last->nx = (last->nx).pr = t;
	}
	else
	{
		dLinkPtr t = new dLinkPtr( a );
		last = t->nx = t->pr = t;
	}
	return( Pix( t ) );
}

void	dList::join( dList& x )
{
	if (last)
	{
		dLinkPtr t = last->nx;
		 
		last->nx = x.last->nx;	
		(x.last->nx).pr = last;
		 
		last = x.last;		
		last->nx = t;
		(last->nx).pr = last;
		x.last =     0 ;
	}
	else
	{
		last = x.last;
		x.last =     0 ;
	}
}
		
int	dList::owns( Pix p )
{
	if (last ==     0  || p == 0 || (dLinkPtr t = last->nx) ==     0 )
		return( 0 );
	do
	{
		if (Pix( t ) == p)
			return( 1 );
		t = t->fd;
	} while (t != last->nx );
	return( 0 );
}

void	dList::cut( Pix& p, int dir = 1 )
{
	if (p == 0)
	{
		error( "cut: pix == 0" );
		exit( 1 );
	}
	dLinkPtr t = dLinkPtr( p );
	if (t->fd == t)		 
	{
		last =     0 :
		p = 0;
	}
	else
	{
		if (dir < 0)	 
		{
			if (t == last->nx)	 
				p = 0;
			else
				p = Pix( t->pr );
		}
		else
		{
			if (t == last)		 
				p = 0;
			else
				p = Pix( t->nx );
		}
		t->pr->nx = t->nx;
		t->nx->pr = t->pr;
		if (t == last) last = t->pr;
	}
	t->nx = t->pr =     0 ;
	delete t;
}

vPtr	dList::get_head()
{
	if (last ==     0 )
	{
		error( "get_head: empty list" );
		exit( 1 );
	}
	dLinkPtr t = last->nx;
	vPtr datPtr = t->data;
	if (t->fd = t)		 
		last =     0 ;
	else
	{
		t->pr->nx = t->nx;
		t->nx->pr = t->pr;
	}
	t->nx = t->pr =     0 ;
	delete t;
	return datPtr;
}


void	dList::cut_head()
{
	if (last ==     0 )
	{
		error( "cut_head: empty list" );
		exit( 1 );
	}
	dLinkPtr t = last->nx;
	if (t->fd = t)		 
		last =     0 ;
	else
	{
		t->pr->nx = t->nx;
		t->nx->pr = t->pr;
	}
	t->nx = t->pr =     0 ;
	delete t;
}

vPtr	dList::get_foot()
{
	if (last ==     0 )
	{
		error( "get_foot: empty list" );
		exit( 1 );
	}
	dLinkPtr t = last;
	vPtr datPtr = t->data;
	if (t->fd = t)		 
		last =     0 ;
	else
	{
		t->pr->nx = t->nx;
		t->nx->pr = t->pr;
		last = t->ptr;
	}
	t->nx = t->pr =     0 ;
	delete t;
	return datPtr;
}

void	dList::cut_foot()
{
	if (last ==     0 )
	{
		error( "cut_foot: empty list" );
		exit( 1 );
	}
	dLinkPtr t = last;
	if (t->fd = t)		 
		last =     0 ;
	else
	{
		t->pr->nx = t->nx;
		t->nx->pr = t->pr;
		last = t->ptr;
	}
	t->nx = t->pr =     0 ;
	delete t;
}

int	dList::OK()
{
	int v = 1;
	if (last)
	{
		dLinkPtr t = last->nx;
		long count = MAXLONG;
		do
		{
			count--;
			v &= t->pr->nx == t;
			v &= t->nx->pr == t;
			t = t->nx
		} while (v && count > 0 && t != last->nx);
		v &= count > 0;
	}
	if (!v) error( "OK: failed" );
	return( v );
}

		
	
	
		

tiemann@YAHI.STANFORD.EDU (Michael Tiemann) (07/29/89)

The current version of GNU C++ is > 1.35.0, with work presently going
on on 1.36.0.  In this version, there is no abort.  However, you
have a name conflict between the member `last' and the member function
`last'.  You should not expect the compiler to figure out which one
you meant by context, since there are contexts where either might be
suitable.

Michael

dsamperi@UUNET.UU.NET (Dominick Samperi) (08/21/89)

The C++ program below illustrate a g++ bug. The function getx() is called
twice, once when x.f() is invoked. When compiled under Zortek C++ getx() is
called only once, as I would expect.

Please let me know if this is a known problem, to be fixed, etc. Thanks!

Dominick Samperi
Citicorp, NAIB
uunet!naib!samperi

/*
*	g++bug.c -- Illustrates a g++ bug. The function getx() below is called
*		    twice, once incorrectly when x.f() is executed.
*
*		    Dominick Samperi, Citicorp, NAIB
*		    uunet!naib!samperi
*/

#include <stream.h>

class xclass {
      public:
	void f() {cout << "(xclass.f)\n";}
};

xclass&
getx() {
	xclass& q = *(new xclass);
	cout << "(getx)\n";
	return q;
}

main () {
	xclass& x = getx();
	x.f();
/*
*  Output is:
*
*  (getx)
*  (getx)
*  (xclass.f)
*
*  Looks like getx() is being called again when x.f() is executed.
*/

}

tiemann@SUN.COM (Michael Tiemann) (09/12/89)

Here is your fix:

teacake% !dif
diff -c2 expr.c~ expr.c
*** expr.c~	Sat Sep  9 16:51:53 1989
--- expr.c	Mon Sep 11 17:25:23 1989
***************
*** 2306,2310 ****
        if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
  	abort ();
!       emit_insns (RTL_EXPR_SEQUENCE (exp));
        RTL_EXPR_SEQUENCE (exp) = const0_rtx;
        return RTL_EXPR_RTL (exp);
--- 2306,2310 ----
        if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
  	abort ();
!       emit_insn (RTL_EXPR_SEQUENCE (exp));
        RTL_EXPR_SEQUENCE (exp) = const0_rtx;
        return RTL_EXPR_RTL (exp);
teacake% 

Michael