Saturday, March 21, 2009

Delphi 2009 behavioural change of "Val"

During the recent migration of a large Delphi for Win32 project (which was started in Delphi 3, and migrated to 5, 7, and 2007 along the way) to Delphi 2009, I encountered some differences in behaviour which were - after some debugging time - ultimately tracked back to the System.Val routine. Here are the details...

We call the Val procedure to convert strings to floating points, using the code parameter to determine if the string was a valid floating point or not (when not, the value is treated as an unknown value). With Delphi 2009, however, all our unknowns became "known" 0 values...

According to the online help: "If the string is invalid, the index of the offending character is stored in Code; otherwise, Code is set to zero."

A little test application shows the difference between Delphi 3-2007 and Delphi 2009:

program valtest;
(*$APPTYPE CONSOLE*)
uses
SysUtils;

var
e: Extended;
code: Integer;

begin
Val('', e, code);
if code = 0 then writeln(e) // Delphi 2009: 0
else
writeln('Error: ', code); // Delphi 2007: Error: 1
readln;
end.
As you can see and experiment for yourself, when passing an empty string to val, the result has always been a code value of 1, meaning (to us) an incorrect or unknown value. With Delphi 2009, the value of code is 0, and the actual converted value is also 0.

Of course, the workaround is easy: add an additional check to see if the string being passed to Val is empty or not. Which that workaround in place, the Delphi 2009 edition of the application works similar to the Delphi 2007 edition (except the new one has support for Unicode in both screens and reports).

No comments: