🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Russ Tuck Thu, 07 Dec 1989 21:01
user-defined conversion bug (1.36.1)
#693
Author: Russ Tuck
Date: Thu, 07 Dec 1989 21:01
537 lines
10053 bytes
The example programs below define classes A and B.  A has operator+, and
B has a user-defined conversion to A.  The issue is an expression which
uses A's + on B's objects, via the B->A conversion.

I posted almost the same program to comp.lang.c++ yesterday, because cfront
2.0 seemed to be in error.  Jonathan Shopiro of AT&T confirmed via mail
that there is a probable bug in cfront, and suggested a workaround which
is probably also better programming practice.  (The workaround is to have
the conversion return an A (value) instead of an A& (reference).)
Unfortunately, the workaround reveals a bug in g++ 1.36.1.

Here are the details...
g++    = GNU g++ 1.36.1
CC.new = AT&T cfront 2.0
piglet = Sun-3/60, SunOS 4.0.3

[Bug 1: conversion fails.]

tuck@piglet> cat type2ae.C
class A {
 public:
  A();
  friend const A operator+ (const A& lsrc, const A& rsrc);
};

class B {
 public:
  B();
  operator const A();
};

main()
{
  A a0;
  B b0, b1;

  a0 = b0 + b1;
}

tuck@piglet> g++ -v -c type2ae.C
gcc version 1.36.1 (based on GCC 1.36)
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Dmc68010 type2ae.C /usr/tmp/cca01090.cpp
GNU CPP version 1.36
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cc1plus /usr/tmp/cca01090.cpp -quiet -dumpbase type2ae.C -version -o /usr/tmp/cca01090.s
GNU C++ version 1.36.1 (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches:
type2ae.C: In function int main ():
type2ae.C:18: default type conversion for type `B' failed

tuck@piglet> CC.new -c type2ae.C
CC  type2ae.C:
cc  -c  type2ae.c

[Bug 2 (related): g++ gets fatal signal when stub fn defns are added.]
 
tuck@piglet> cat type2af.C
class A {
 public:
  A();
  friend const A operator+ (const A& lsrc, const A& rsrc);
};

class B {
 public:
  B();
  operator const A();
};

extern "C" {
#include <stdio.h>
}

A::A()
{
  printf("A::A();\n");
}

const A operator+(const A& lsrc, const A& rsrc)
{
  printf("const A operator+(const A& lsrc, const A& rsrc)\n");
  A ta;
  return(ta);
}

B::B()
{
  printf("B::B();\n");
}

B::operator const A()
{
  printf("operator const A()\n");
  A* pa = new A;
  return(*pa);
}

main()
{
  A a0;
  B b0, b1;

  a0 = b0 + b1;
}

[diff to show nothing changed, just added defns]
tuck@piglet> diff type2ae.C type2af.C
diff type2ae.C type2af.C
12a13,40
> extern "C" {
> #include <stdio.h>
> }
> 
> A::A()
> {
>   printf("A::A();\n");
> }
> 
> const A operator+(const A& lsrc, const A& rsrc)
> {
>   printf("const A operator+(const A& lsrc, const A& rsrc)\n");
>   A ta;
>   return(ta);
> }
> 
> B::B()
> {
>   printf("B::B();\n");
> }
> 
> B::operator const A()
> {
>   printf("operator const A()\n");
>   A* pa = new A;
>   return(*pa);
> }
> 
tuck@piglet> g++ -v -c type2af.C
gcc version 1.36.1 (based on GCC 1.36)
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Dmc68010 type2af.C /usr/tmp/cca01134.cpp
GNU CPP version 1.36
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cc1plus /usr/tmp/cca01134.cpp -quiet -dumpbase type2af.C -version -o /usr/tmp/cca01134.s
GNU C++ version 1.36.1 (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches:
type2af.C: In method B::operator const class A ():
type2af.C:38: Segmentation violation
g++: Program cc1plus got fatal signal 11.
tuck@piglet> CC.new type2af.C
CC  type2af.C:
"type2af.C", line 22: warning:  lsrc not used
"type2af.C", line 22: warning:  rsrc not used
cc  -L/usr/local/lib/CC2.0   type2af.c -lC
tuck@piglet> a.out
A::A();
B::B();
B::B();
operator const A()
A::A();
operator const A()
A::A();
const A operator+(const A& lsrc, const A& rsrc)
A::A();


[This is the similar program which shows the cfront error.  g++ does fine.]
[The only difference is that the conversion is to A& instead of A.        ]

tuck@piglet> diff type2af.C type2ag.C
10c10
<   operator const A();
---
>   operator const A&();
34c34
< B::operator const A()
---
> B::operator const A&()
tuck@piglet> cat type2ag.C
class A {
 public:
  A();
  friend const A operator+ (const A& lsrc, const A& rsrc);
};

class B {
 public:
  B();
  operator const A&();
};

extern "C" {
#include <stdio.h>
}

A::A()
{
  printf("A::A();\n");
}

const A operator+(const A& lsrc, const A& rsrc)
{
  printf("const A operator+(const A& lsrc, const A& rsrc)\n");
  A ta;
  return(ta);
}

B::B()
{
  printf("B::B();\n");
}

B::operator const A&()
{
  printf("operator const A()\n");
  A* pa = new A;
  return(*pa);
}

main()
{
  A a0;
  B b0, b1;

  a0 = b0 + b1;
}

tuck@piglet> g++ -v type2ag.C -lg++
gcc version 1.36.1 (based on GCC 1.36)
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Dmc68010 type2ag.C /usr/tmp/cca01166.cpp
GNU CPP version 1.36
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cc1plus /usr/tmp/cca01166.cpp -quiet -dumpbase type2ag.C -version -o /usr/tmp/cca01166.s
GNU C++ version 1.36.1 (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches:
 /usr/softlab/contrib/lib/m68k_sunos/gcc-as -mc68010 -o type2ag.o /usr/tmp/cca01166.s
 /usr/softlab/contrib/lib/m68k_sunos/gcc-ld /lib/crt0.o type2ag.o -lg++ -lg++ /usr/softlab/contrib/lib/m68k_sunos/gcc-gnulib -lc
tuck@piglet> a.out
A::A();
B::B();
B::B();
operator const A()
A::A();
operator const A()
A::A();
const A operator+(const A& lsrc, const A& rsrc)
A::A();
tuck@piglet> CC.new type2ag.C
CC  type2ag.C:
"type2ag.C", line 22: warning:  lsrc not used
"type2ag.C", line 22: warning:  rsrc not used
"type2ag.C", line 46: error: ambiguous use of overloaded +:  B  and  B 
1 error

[Now for completeness, here's the preprocessor output from the file that ]
[causes the fatal signal.                                                ]
 
tuck@piglet> g++ -v -E type2af.C
gcc version 1.36.1 (based on GCC 1.36)
 /usr/softlab/contrib/lib/m68k_sunos/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Dmc68010 type2af.C
GNU CPP version 1.36
# 1 "type2af.C"
class A {
 public:
  A();
  friend const A operator+ (const A& lsrc, const A& rsrc);
};

class B {
 public:
  B();
  operator const A();
};

extern "C" {
# 1 "/usr/softlab/contrib/include/g++-include/stdio.h" 1
 
 





















 




























#pragma once


 












# 79 "/usr/softlab/contrib/include/g++-include/stdio.h"





# 108 "/usr/softlab/contrib/include/g++-include/stdio.h"














 
 

 


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

    int     _bufsiz;
    short   _flag;








    char    _file;






} _iob[];










# 171 "/usr/softlab/contrib/include/g++-include/stdio.h"
































extern "C" {

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

 
 

int    vprintf(const char*, ... );





char*  sprintf(char*, const char* ...);
char*  vsprintf(char*, const char*, ...);


}
















# 14 "type2af.C" 2

}

A::A()
{
  printf("A::A();\n");
}

const A operator+(const A& lsrc, const A& rsrc)
{
  printf("const A operator+(const A& lsrc, const A& rsrc)\n");
  A ta;
  return(ta);
}

B::B()
{
  printf("B::B();\n");
}

B::operator const A()
{
  printf("operator const A()\n");
  A* pa = new A;
  return(*pa);
}

main()
{
  A a0;
  B b0, b1;

  a0 = b0 + b1;
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads