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