[comp.lang.c++] Destruction of temporaries in g++?

johner@elaine19.Stanford.EDU (John Lynch) (06/06/91)

I have ported a large commercial class library which is supported on
cfront to g++.  For the most part, I have been succesful in convincing
everything to work, but I am having some problems in their String
class which I believe are due to the earlier destruction of
temporaries in g++ vs. cfront.

Essentially, they do case-insensitive string comparisons with the
usual method of upper-casing both strings and comparing them. This
basically looks like:

return strcmp(toUpper(*this).data(),toUpper(other).data());

where toUpper returns an uppercase copy of the string. This seems to
work on cfront based compilers, but in g++, the destructors for the
temporaries seem to get called before the comparison is done.

Actually, stepping through it, what seems to happen is the temporary
is created for the toUpper call, then the destructor is called, then a
temporary is created with the default constructor, then the data()
function is called for that second temporary.

In other words, the temporay uppercase is returned and immediately
destroyed.  A second, "empty" string gets the data() call.

I wrote a small sample string class which exhibits the behavior:

#include <stream.h>
#include <stdio.h>
#include <string.h>

#define NL "\n"

struct myString {
	char cdata[255];
	const char* data() const{ return cdata;}
	myString(const char *c) {	strcpy(cdata,c);}
	~myString(){strcpy(cdata,"zxxxxxxxxxxxxxxxxxx");}
};

myString copy(const myString& theStr)
{
	myString temp(theStr.data());
	return temp;
}
	

int docompare(const char *c1,const char *c2)
{
	cout << "c1 = " << c1 << NL;
	cout << "c2 = " << c2 << NL;
	return strcmp(c1,c2);
}


main()
{

	myString s1("Hi there.");
	myString s2("Goodbye");
	int i = docompare(copy(s1).data(),copy(s2).data());
	cout << i << NL;
}
	

The destructor puts the garbage in its data because what is happening
(I think) is  second temporary gets created in the same place in
memory as the previous one had existed, so its data() call returns the
data left by the previous temporary.

Anyway, the results of cfront and g++ tests are below:

elaine19.Stanford.EDU 15> testCC
c1 = Hi there.
c2 = Goodbye
1
elaine19.Stanford.EDU 16> testg++
c1 = zxxxxxxxxxxxxxxxxxx
c2 = zxxxxxxxxxxxxxxxxxx
0

My question is: is this indeed what is going on? Is there an easy way
around this? I have the source, so I could rewrite it just keeping
track of the copy returned from toUpper explicitly, but they use
this construct often in the String class, and possibly elsewhere.

Thanks for any help,
John