www.digitalmars.com         C & C++   DMDScript  

c++ - Compiling problem.

reply John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I have some code which compiles and runs sometimes, with Digital Mars.
The problem is one of the use of overloaded operators within a class. I
will  discuss this in relation to the following class definition.

template < class T > class X
{
  T t;
  public :
  X() : t(T(0)) { }
  X(T tt) : t(tt) { }
 ~X() { }
  T gett() const { return t; }
  X<T> operator +(const X&);
  X<T> operator -(const X&);
  friend X<T> operator *(const X&,const X&);
};

I have been using code like that for operator + and - above, where the
operator is a member function rather than an operator.  The point is
that it compiled and ran until the other day when I started doing things
such as

ans = a+b+c;

when it mysteriously crashed.  I have traced this to the fact that the
friend operator does much more work with registers BETWEEN and AFTER the
calls.

This is an issue of how to go about things - Stroustrup in "The Design
and Evolution of C++" p.81 recommends the friend operator.

But it is also an issue of code which runs and does funny things. I
attach files

xa.h xatest.cpp and xatest.unm (unmangled machine code)

Note that the example corrupts one of the input arguments:

Digital Mars version is 2050
 a = 1, b = 2, c = 3
 a = -1, b = 2, c = 3
a+b+c = 6
a*b*c = 6
a-b-c = -4

John Fletcher
Mar 29 2001
next sibling parent John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit



John Fletcher wrote:

 xa.h xatest.cpp and xatest.unm (unmangled machine code)

 John Fletcher

Oops my finger slipped as I was putting on the unmangled code. Here it is. John
Mar 29 2001
prev sibling next sibling parent John Fletcher <J.P.Fletcher aston.ac.uk> writes:
John Fletcher wrote:

 I have some code which compiles and runs sometimes, with Digital Mars.
 The problem is one of the use of overloaded operators within a class. I
 will  discuss this in relation to the following class definition.

 I have been using code like that for operator + and - above, where the
 operator is a member function rather than an operator.  The point is
 that it compiled and ran until the other day when I started doing things
 such as

Oops again, the sentence starting the last paragraph should read: I have been using code like that for operator + and - above, where the operator is a member function rather than a FRIEND operator. John
Mar 29 2001
prev sibling next sibling parent reply John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

There is more to this than I thought.

Look at the following.

// Type 2 - friend function.
template <class T>
X<T> operator * (const X<T> &arg1, const X<T> &arg2)
{
    return X<T>(arg1.t*arg2.t);
}

// Type 2a - friend function with temporary
template <class T>
X<T> operator + (const X<T> &arg1, const X<T> &arg2)
{
   X<T> temp(arg1.t+arg2.t);
// Adding something like this changes the program behaviour.
   cout << temp.gett() << endl;
   return temp;
}

The print statement in the second function modifies the program behaviour in my
full
example.  In that case without the print the program hangs for 30 seconds.

In the short example without the print, the two functions compile to the same
machine
code. I am doing no optimisations..

Attachments xb.h and xbtest.cpp

John
Mar 29 2001
parent John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Here is an extract from the disassembled code which is operating in my full
example.

The code hangs unless the print statement is compiled.

John
Mar 29 2001
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
I compiled your example with:

    sc xatest -o -XD

and

    sc xatest -XD

with version 8.1B2n, and it compiled and ran successfully both times.
Specifically:

E:\bug>sc xatest -XD -o
link test,,,user32+kernel32/noi;


E:\bug>xatest
Digital Mars version is 2066
 a = 1, b = 2, c = 3
 a = -1, b = 2, c = 3
a+b+c = 6
a*b*c = 6
a-b-c = -4

E:\bug>scppn
Digital Mars C/C++ Compiler Version 8.1B2n
Copyright (C) Digital Mars 2000-2001.  All Rights Reserved.
Written by Walter Bright
www.digitalmars.com

John Fletcher wrote in message <3AC315EB.62C03124 aston.ac.uk>...
I have some code which compiles and runs sometimes, with Digital Mars.
The problem is one of the use of overloaded operators within a class. I
will  discuss this in relation to the following class definition.

template < class T > class X
{
  T t;
  public :
  X() : t(T(0)) { }
  X(T tt) : t(tt) { }
 ~X() { }
  T gett() const { return t; }
  X<T> operator +(const X&);
  X<T> operator -(const X&);
  friend X<T> operator *(const X&,const X&);
};

I have been using code like that for operator + and - above, where the
operator is a member function rather than an operator.  The point is
that it compiled and ran until the other day when I started doing things
such as

ans = a+b+c;

when it mysteriously crashed.  I have traced this to the fact that the
friend operator does much more work with registers BETWEEN and AFTER the
calls.

This is an issue of how to go about things - Stroustrup in "The Design
and Evolution of C++" p.81 recommends the friend operator.

But it is also an issue of code which runs and does funny things. I
attach files

xa.h xatest.cpp and xatest.unm (unmangled machine code)

Note that the example corrupts one of the input arguments:

Digital Mars version is 2050
 a = 1, b = 2, c = 3
 a = -1, b = 2, c = 3
a+b+c = 6
a*b*c = 6
a-b-c = -4

John Fletcher

Mar 29 2001
parent reply John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Walter wrote:

 I compiled your example with:

     sc xatest -o -XD

 and

     sc xatest -XD

 with version 8.1B2n, and it compiled and ran successfully both times.
 Specifically:

 E:\bug>sc xatest -XD -o
 link test,,,user32+kernel32/noi;

 E:\bug>xatest
 Digital Mars version is 2066
  a = 1, b = 2, c = 3
  a = -1, b = 2, c = 3
 a+b+c = 6
 a*b*c = 6
 a-b-c = -4

Yes, sorry, that is correct operation, because putting *this = result in the operator - makes the first subtraction a -= b which does change a as a side effect. I have reached the conclusion that the original problem was not so much in the code structure as in the level of demand being placed on the system by my code. I have restructured it to reduce the amount of work. By the way, what is the significance of the numbers returned by __DMC__? Thanks John
Mar 30 2001
parent reply "Walter" <walter digitalmars.com> writes:
John Fletcher wrote in message <3AC4538B.7065E4FA aston.ac.uk>...
By the way, what is the significance of the numbers returned by __DMC__?

If you printf it in hex notation, it is the version number of the compiler.
Mar 30 2001
parent reply John Fletcher <J.P.Fletcher aston.ac.uk> writes:
Walter wrote:

 John Fletcher wrote in message <3AC4538B.7065E4FA aston.ac.uk>...
By the way, what is the significance of the numbers returned by __DMC__?

If you printf it in hex notation, it is the version number of the compiler.

Is there a way to tell stream output that is what is wanted? John
Mar 30 2001
parent "Walter" <walter digitalmars.com> writes:
In iostream.h, there's a flag called 'hex' and some associated functions to
get/set the flag. Myself, I just use printf.

John Fletcher wrote in message <3AC467C8.90A24BA6 aston.ac.uk>...
Walter wrote:

 John Fletcher wrote in message <3AC4538B.7065E4FA aston.ac.uk>...
By the way, what is the significance of the numbers returned by __DMC__?

If you printf it in hex notation, it is the version number of the


Is there a way to tell stream output that is what is wanted?

John

Mar 30 2001