The following code had been in Production use for 10 years at my company. It started crashing when we converted from vc6 to vc8: selectSql += "SELECT FieldA, FieldB, FieldC FieldD from TableA where ORG_ID = 'xxx'"; rc = rs.open(selectSql); while ( !rs.isEOF() && !rs.isError() ) { pInput = new PDUpdateInput; pInput->FieldAValue = rs.getResultLong(0); pInput->FieldBValue = rs.getResult(1); pInput->FieldCValue = rs.getResult(2); pInput->FieldDValue = rs.getResult(3); // Crashed here! lst->push_back(pInput); rc = rs.moveNext(); } rs.close(); Obviously, we never used FieldD for anything, because that value was never retrieved! The comma is missing between FieldC and FieldD in the Select statement. That makes the string 'FieldD' an alias to FieldC. Apparently, the security in vc8 is stepped up (compared to vc6), so when trying to access rs.getResult(3) it crashed since there are only 3 values in the resultset, not 4. This didn't take long at all to find/fix. But it's amazing sometimes how long bugs can be in Production code and stay hidden.
Patrick D Owens
Posts
-
Those missing commas... -
3rd Party Grids, Tree Controls, editorsI have a simple question. I have inherited a VC++ application that uses a 3rd party software (Roguewave Stingray) for its GUI grids, tree controls, etc. Since I inherited this app, plus the fact that I don't have much experience writing large pc-based apps from scratch, my question is: What is the advantage of using 3rd party tools for grids, tree controls, etc.? Doesn't MFC have this functionality built in, or is it just not robust enough for large-scale apps? My app is approx. 8 years old, so is the answer to this question different now than it was 8 years ago? Thanks for any feedback. Pat
-
overload resolution in VC 6.0Thanks Joaquin, You are right on in your analysis. The result of line (3) is the value of lTemp1 "stringed", exactly as you broke it down. In fact, I thought my overload of PString + PString was working, but I stepped into the code with the debugger, and it wasn't going to my PString overload of '+', but to the CString overload of '+'. So it was doing a PString to CString conversion for me behind the scenes.. In researching this problem, the only thing I could come up with is that there are 2 ways to override the operators. One is to have a 'friend' function within the class. The other is to define it globally, outside the class. So I took my + overrides out of the PString class and defined them globally. Now things seem to be working just fine. I guess there was some scope issues. BTW, in reading about the C2666 error, I did read that the reason behind errors like this is because Microsoft is implementing/enforcing more of the accepted C++ standards, just as you speculated. Thanks for your analysis on this one. Pat
-
overload resolution in VC 6.0I tried strTemp2 = strTemp1 + (long)lTemp1; and it still gives the C2666 error. I agree that it probably can't decide the type of that second value, but I have tried changing the overload definitions to PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, const long& value); and PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, long& value); and PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, long value); From what I have read on this error in the help pages, if the compiler can't find an exact match, then it will try to do some conversions to get a match. You would think that one of the above 3 overloaded definitions would give an exact match so the compiler wouldn't have to do any conversions. But I guess I am missing something. I assume the first argument is fine because I can add a PString and a PString. So it must be something with the second (long) argument, but I can't figure it out. Pat
-
overload resolution in VC 6.0I have a PString class that derives from CString. In it, I overload the + operator so I can add a PString and long variable to give me a new PString. It works fine in VC 5.0, but while converting to VC 6.0, I get a C2666 error saying it cannot determine which overloaded + to use. Here is the code segment: PString strTemp1 = "abc"; long lTemp1 = 123; PString strTemp2 = "def"; (1) strTemp2 = strTemp1 + strTemp2; // works fine. (2) strTemp2 = strTemp1 + lTemp1; // C2666 error. (3) strTemp2 = +(strTemp1, lTemp1); // no error. (4) strTemp2 = ::operator +(strTemp1, lTemp1); // no err class PString : public CString { public: .... PCSGENRL_EXP_TYPE friend PString operator +( const PString& string1, const PString& string2 ); PCSGENRL_EXP_TYPE friend PString operator +( const PString& string, TCHAR ch ); PCSGENRL_EXP_TYPE friend PString operator +( TCHAR ch, const PString& string ); PCSGENRL_EXP_TYPE friend PString operator +( const PString& string, LPCTSTR lpsz ); PCSGENRL_EXP_TYPE friend PString operator +( LPCTSTR lpsz, const PString& string ); PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const long& value); PCSGENRL_EXP_TYPE friend PString operator +(const long& value, const PString& string); PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const double& value); PCSGENRL_EXP_TYPE friend PString operator +(const double& value, const PString& string); PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const int& value); PCSGENRL_EXP_TYPE friend PString operator +(const int& value, const PString& string); PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, const ULONG& value); PCSGENRL_EXP_TYPE friend PString operator +(const ULONG& value,const PString& string); Why does line (2) give an error, while lines (3) and (4) give no compile error? Aren't they the same instruction? Any help would be appreciated. Pat