我正在将代码从Delphi 10 Seattle升级到Delphi 10.2 Tokyo并获得大量H2077提示值分配给…从未用于作业.
(即使在过去明确添加这些内容以摆脱’可能没有价值’警告的地方).
(即使在过去明确添加这些内容以摆脱’可能没有价值’警告的地方).
这些都是初始化的函数,如:
Result := 0; ...
要么:
Result := ftType1; // where ftType1 is an enumerated type ...
编译器在检测这些内容时是否变得更聪明,或者在函数的初始返回值方面发生了哪些变化?
我们总是在’on’上有这些提示,而且我总是构建(不编译).
示例函数(1)在西雅图没有提示,
但是在东京的第一个结果:= 0行中给出了分配给’GetDatabaseDialect’的提示H2077值.
function GetDatabaseDialect(dbname,User,Pswd: string) : integer; var status: array[1..19] of longint; szdbname,szDbParam: PANSIChar; dbHandle : pointer; rslt: longint; lDPBBuffer : ANSIString; lDPBLength : integer; cItem: ANSIChar; szRslt: PANSIChar; //array[0..IBResultBufferSize-1] of ANSIChar; begin Result := 0; dbHandle := nil; // init database parameter block with version number lDPBBuffer := ''; SetLength(lDPBBuffer,1); lDPBBuffer[1] := ANSIChar(isc_dpb_version1); lDPBLength := 1; // fill Database Parameter Buffer with user name/password lDPBBuffer := lDPBBuffer + ANSIChar(isc_dpb_user_name) + ANSIChar(Length(User)) + ANSIString( User ); Inc(lDPBLength,2 + Length(User)); lDPBBuffer := lDPBBuffer + ANSIChar(isc_dpb_password) + ANSIChar(Length(Pswd)) + ANSIString( Pswd ); Inc(lDPBLength,2 + Length(Pswd)); //Pointers naar naam + buffer szdbname := PANSIChar(ANSISTring(dbname)); szDbParam := PANSIChar( lDPBBuffer ); // attach to the database and set dialect rslt := isc_attach_database(@status,szdbname,@dbHandle,lDPBLength,szDbParam); if rslt <> 0 then raise EDatabaseError.Create('Error attaching database! ISC# ' + IntToStr(rslt)); //Haal sql dialect op szRslt := Allocmem(1000); try FillChar( szRslt^,1000,0); cItem := ANSIChar( isc_info_db_sql_dialect ); rslt := isc_database_info(@status,@DBHandle,1,@cItem,szRslt); if rslt <> 0 then raise EDatabaseError.Create('Error retrieving database info ! ISC# ' + IntToStr(rslt)); Result := Ord(szRslt[3]); //3e positie is dialect finally FreeMem(szRslt); end; // Drop the connection to the database rslt := isc_detach_database(@status,@dbHandle); if rslt <> 0 then raise EDatabaseError.Create('Error detaching database! ISC# ' + IntToStr(rslt)); end;
来自第三方库的示例(2)似乎没有针对东京进行优化,
用枚举类型说明这种情况:
H2077未分配给’TppTemplate.StreamType’的值
请注意,将分配更改为Result:= ftASCII;不会使提示消失(我最初的假设是它与第一个枚举值相关联是不正确的).
type TppformatType = (ftBinary,ftASCII); function TppTemplate.StreamType(aStream: TStream): TppformatType; var lSavePos: Integer; begin {save stream position} lSavePos := aStream.Position; Result := ftBinary; try ComputeOffsetFromStream(aStream); aStream.Seek(FOffset,soBeginning); if IsValidASCIISignature(aStream) then Result := ftASCII else if IsValidBinarySignature(aStream) then Result := ftBinary else raise EInvalidTemplateError.Create(ppLoadStr(49)); finally {restore stream position} aStream.Seek(lSavePos,soBeginning); end; end; {function,StreamType}
共同点似乎是结果分配在try / finally块中.
解决方法
请考虑此代码,并尽量少复制您的场景:
function Bar: Boolean; begin Result := Random<0.5; end; function Foo: Integer; begin Result := 0; if Bar then Result := 1 else raise Exception.Create(''); end;
编译器,甚至是旧版本,都会发出以下提示:
[dcc32 Hint]: H2077 Value assigned to ‘Foo’ never used
这是合理的.对Result的第一个赋值是没有意义的,可以删除.
现在考虑这种变化:
function Foo: Integer; begin Result := 0; try if Bar then Result := 1 else raise Exception.Create(''); finally end; end;
较旧版本的编译器不再发出提示,但最新版本的编译器会发出提示.对于旧版本,这应该被视为编译器缺陷.上面显示的两个Foo变体在语义上是相同的.编译器在生成相同代码时是合理的.
正如您所推测的那样,在try / finally块中的赋值对于触发先前版本中的缺陷是必要的.
我们可以得出结论,Embarcadero开发人员已经修复了东京的缺陷.您可以通过删除虚假的初始分配来解决提示.
当然,如果您的代码是由旧版本的编译器以及新版本编译的,那么您就处于绑定状态.使用现在的代码,新版本的编译器会发出提示.删除初始赋值,旧版本的编译器会发出提示.