2017-07-18 1 views
4

Je suis en train de mettre à jour le code de Delphi 10 Seattle à Delphi 10.2 Tokyo et obtenir beaucoup d'indices H2077 Value assigned to ... never used sur les affectations.
(Même dans les endroits où ceux-ci ont été ajoutés explicitement dans le passé pour se débarrasser des avertissements 'peut ne pas avoir de valeur').Le code d'initialisation de la fonction a-t-il changé de Seattle à Tokyo?

Ceux-ci sont toutes les fonctions initialisés comme:

Result := 0; 
... 

Ou:

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

Est-ce que le compilateur obtenir plus intelligent pour détecter ceux-ci ou a changé quelque chose en ce qui concerne les valeurs de retour initiales des fonctions?

Nous avons toujours eu ces conseils 'sur', et je construis toujours (pas compiler).

fonction Exemple (1) qui construit sans conseils à Seattle,
mais donne l'indice H2077 Value assigned to 'GetDatabaseDialect' not used sur la première ligne Result := 0 à Tokyo.

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; 

Exemple (2) à partir d'une bibliothèque tierce partie qui ne semble pas être optimisé pour Tokyo,
illustrant le cas des types énumérés:
H2077 Value assigned to 'TppTemplate.StreamType' not used
Notez que la modification de la cession à Result := ftASCII; ne fait pas l'indice disparaît (mon hypothèse initiale selon laquelle il était associé à la première valeur d'énumération était incorrecte).

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} 

Le dénominateur commun semble être les affectations de résultats dans les blocs try/finally.

+0

FWIW, ce serait un compilateur plus intelligent, pas un code d'initialisation de fonction qui a changé. –

+2

Dans certains cas, le compilateur ne reconnaissait pas correctement qu'une variable ou un résultat était défini dans chaque chemin de code. Maintenant, il le fait et reconnaît ainsi que les valeurs assignées auparavant ne sont plus nécessaires. –

+0

@David, ouais et vous construisez ce MCVE dans les deux versions et dites, ouais ils diffèrent, on génère un indice tandis que l'autre ne le fait pas, je ne sais pas pourquoi mais il doit y avoir quelques changements. C'est quelque chose que EMBT devrait répondre à un rapport de bogue. – Victoria

Répondre

6

Considérez ce code avec une reproduction minimale de votre scénario:

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; 

Le compilateur, des versions encore plus anciennes, émet l'indication suivante:

[Astuce dcc32]: H2077 Valeur affectée à ' Foo 'jamais utilisé

Ceci est raisonnable. La première affectation à Result est inutile et peut être supprimée.

Considérons maintenant cette variation:

function Foo: Integer; 
begin 
    Result := 0; 
    try 
    if Bar then 
     Result := 1 
    else 
     raise Exception.Create(''); 
    finally 
    end; 
end; 

Les anciennes versions du compilateur n'émettent plus l'indice, mais la dernière version du compilateur fait. Cela devrait être considéré comme un défaut du compilateur, pour les anciennes versions. Les deux variantes de Foo montrées ci-dessus sont sémantiquement identiques. Le compilateur serait justifié de générer un code identique.

Comme vous le supposez, l'affectation se trouvant dans le bloc try/finally est nécessaire pour déclencher le défaut dans les versions précédentes.

Nous pouvons conclure que les développeurs Embarcadero ont corrigé un défaut à Tokyo.Vous pouvez résoudre les astuces en supprimant les affectations initiales parasites.

Bien sûr, si votre code doit être compilé par des versions plus anciennes du compilateur, ainsi que par de nouvelles versions, vous êtes dans une liaison. Avec le code tel qu'il est maintenant, un indice est émis par les nouvelles versions du compilateur. Supprimez l'affectation initiale et un indice est émis par les anciennes versions du compilateur.

+0

Je voudrais simplement désactiver cet indice particulier (est-ce possible?) Dans les anciennes versions. Si elle compile sans allusion dans la version la plus récente, ou si j'ignorerais simplement les indices dans les versions précédentes, tant qu'il n'y en a pas dans la version la plus récente. –

+0

@RudyVelthuis Les avertissements individuels peuvent être supprimés, mais les indices sont tout ou rien. –

+0

Est-ce qu'il me manque quelque chose ici? Dans mon deuxième exemple avec le type énuméré, supposons que l'initialisation était 'Result: = ftAscii;'. Maintenant, je reçois l'indice du compilateur, supprime cette ligne. Que faire si une exception est générée dans ComputeOffsetFromStream? L'exécution sauterait au final et le résultat serait indéfini. ** Mais le compilateur ne me prévient pas ** comme par le passé. Je ne suis pas sûr que c'est une amélioration ... –