2015-01-30 9 views
8

Perché questo codice:Str in XE7 genera strano avvertimento

w: word; 
    s: String; 
begin 
    str(w, s); 

generare questo avviso in XE7:

[dcc32 Warning] Unit1.pas(76): W1057 Implicit string cast from 'ShortString' to 'string' 

Tom

+0

Uno dei tanti avvertimenti del compilatore che ho avuto a che fare con il dato che l'aggiornamento da XE2 a XE7. –

+0

Il compilatore genera effettivamente una chiamata a _StrLong che restituisce una sequenza di stringhe. Questa non è una risposta, naturalmente. –

+0

@Jerry - Questo è lo stesso per XE2. –

risposta

5

System.Str è una funzione intrinseca che risale a un'epoca byegone . Il documentation dice questo:

procedure Str (const X [: Width [: Decimals]]; var S: String);

....

Note: Tuttavia, sull'utilizzo di questa procedura, il compilatore può emettere un avvertimento: W1057 fusione stringa implicita dal '% s' a '% s' (Delphi).

Se non è necessaria una stringa con una lunghezza minima predefinita, provare invece a utilizzare la funzione IntToStr.

Dato che questo è intrinseco, è probabile che si stia verificando qualcosa in più. Dietro le quinte, la funzione intrinseca è implementata da una chiamata a una funzione di supporto RTL che produce uno ShortString. La magia del compilatore lo trasforma in un string. E ti avverte della conversione implicita. La magia compilatore trasforma

Str(w, s); 

in

s := _Str0Long(w); 

Dove _Str0Long è:

function _Str0Long(val: Longint): _ShortStr; 
begin 
    Result := _StrLong(val, 0); 
end; 

Dal _Str0Long restituisce un ShortString poi il compilatore deve generare il codice per eseguire la converstion implicita da ShortString a string quando assegna alla variabile s. E naturalmente è naturale che tu veda W1057.

La riga di fondo è che Str esiste solo per mantenere la compatibilità con il codice precedente Pascal ShortString. Il nuovo codice non dovrebbe chiamare Str. Si dovrebbe fare quello che dice la documentazione e chiamare IntToStr:

s := IntToStr(w); 

O forse:

s := w.ToString; 
+0

Assegnare System.Str a ShortString è un modo per convertire un intero in testo senza colpire l'allocazione della memoria heap. –

+0

@LURD True dat. Direi che ci sono modi migliori. In ogni caso, qui assegniamo a 'string'. Ma per quei casi limite in cui perf è critico, si può fare un caso per evitare l'heap con 'Str'. –

+0

David: mi hai mostrato una grande moderazione non includendo "RTFM" nel tuo post. Grazie per la tua solita risposta approfondita. Poiché stiamo migrando più di un milione di righe di codice, eseguirò il percorso "modifica il meno possibile" in questa prima fase utilizzando $ WARNINGS OFF nelle poche righe di codice che invocano questo. (In realtà sono Str (w: 3: 1, S), quindi c'è un po 'di più rispetto al semplice esempio che ho fornito ... – Tom