函数初始化代码是否从西雅图更改为东京?

Has function initialization code changed from Seattle to Tokyo?

我正在将代码从 Delphi 10 Seattle 升级到 Delphi 10.2 Tokyo 并在作业中得到很多 H2077 提示 Value assigned to ... never used
(即使在过去明确添加这些以消除 'may not have a value' 警告的地方)。

这些都是函数初始化如下:

Result := 0;
...

或:

Result := ftType1; // where ftType1 is an enumerated type
...

编译器是否在检测这些方面变得更聪明了,或者在函数的初始 return 值方面发生了一些变化?

我们一直有这些提示'on',我总是构建(而不是编译)。

在西雅图没有提示的情况下构建的示例函数 (1),
但在东京的第一 Result := 0 行给出提示 H2077 Value assigned to 'GetDatabaseDialect' not used

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, 0, 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, 1000, 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 Value assigned to 'TppTemplate.StreamType' not used
请注意,将分配更改为 Result := ftASCII; 不会使提示消失(我最初假设它与 first 枚举值相关联是不正确的)。

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 开发人员修复了东京的一个缺陷。您可以通过删除虚假的初始分配来解决提示。

当然,如果您的代码既要被旧版本的编译器编译,又要被新版本编译,那么您就陷入困境了。对于现在的代码,新版本的编译器会发出提示。删除初始分配,旧版本的编译器会发出提示。