rae@gpu.utcs.toronto.edu (Reid Ellis) (12/21/90)
I posted the following earlier, but I gave it a distribution of "local" by
mistake. Sorry if anyone sees this twice!
---
I've been trying to create pseudo-base-types -- that is, classes which emulate
almost all of the behaviour of a base type -- and have run into what appears
to be a bug.
When I compile the source below on an SGI machine, I have no problem. If I
compile it on a Macintosh, I get the error shown below. It looks as if the
compiler is trying to cast a double to an int for some reason. Can't figure
why, since both the parameter and the expected return value are both
unambiguously double.
File "fakeInt.cp"; line 48 # error: two standard conversions possible
for abs(): double (double ) and int (int )
Here's my cfront version:
<< CFront Version 1.0 (9/11/90; AT&T 2.0) *Apple Computer, Inc. 1989-90 >>
^-- Mac '(c)' character
Note that on an SGI, the "#expr" preprocessor directive does not work, thus
the #ifdef's..
---8<-----c-u-t-----h-e-r-e------->8---------
#include <stream.h>
#ifdef sgi
# define try(expr) \
if(expr) cout << "yes "; else cout << "no "; cout << "expr \n" ;
# define show(type, expr) \
cout << "expr = " << (type &)(expr) << '\n';
#else
# define try(expr) \
if(expr) cout << "yes "; else cout << "no "; cout << #expr "\n" ;
# define show(type, expr) \
cout << #expr " = " << (type &)(expr) << '\n';
#endif
inline double abs(double d) { return (d >= 0.0) ? d : -d; }
inline int abs(int d) { return (d >= 0.0) ? d : -d; }
struct Tint
{
Tint() {}
Tint(const int &i) : value(i) {}
Tint(const Tint &t) : value(t.value) {}
operator int &()
{ return value; }
int operator==(const Tint &t) const
// this is a bit whimsical ...
{ return abs(value - t.value) <= 1; }
int operator==(const int &i) const
{ return value == i; }
private:
int value;
};
struct Tdouble
{
Tdouble() {}
Tdouble(const double &d)
: value(d) {}
Tdouble(const Tdouble &d)
: value(d.value) {}
static const double kEpsilon;
operator double &()
{ return value; }
int operator==(const Tdouble &d) const
{ return (abs(value - d.value) < kEpsilon); } // <=== line 48
int operator==(const double &d) const
{ return value == d; }
private:
double value;
};
const double Tdouble::kEpsilon = 0.1;
const double kInit = 1.0;
const double kInit2 = 1.003;
void main()
{
int i1 = 1;
int i2 = 2;
Tint x1 = 1;
Tint x2 = 2;
// if I try saying "d1 = 1.0" below, it complains about
// "cannot make a Tdouble from a long double"..
Tdouble d1 = kInit;
Tdouble d2 = kInit2;
show(int, i1);
show(int, i2);
show(int, x1);
show(int, x2);
show(double, d1);
show(double, d2);
try(i1 == x1);
try(x1 == x2);
try(x2 == x1);
try(d1 == d2);
d2 += 0.1;
show(double, d2);
try(d1 == d2);
}