2015-01-30 6 views
8

Dlaczego ten kod:Str w XE7 generuje dziwne ostrzeżenie

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

wygenerowania tego ostrzeżenia w XE7:

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

Tom

+0

jeden z wielu ostrzeżeń kompilatora mam do czynienia z od uaktualniania XE2 do XE7. –

+0

Kompilator faktycznie generuje wywołanie funkcji _StrLong, która zwraca skrót. To oczywiście nie jest odpowiedź. –

+0

@Jerry - To samo dotyczy XE2. –

Odpowiedz

5

System.Str jest nieodłącznym funkcja, która pochodzi z byegone ery . documentation mówi:

procedura Str (const X [: Szerokość [: miejsca dziesiętne]]; var S: String);

....

Uwagi: Jednak na Stosując tę ​​procedurę, kompilator może wydać ostrzeżenie: W1057 niejawnej obsady ciąg z '% s' do '% s' (Delphi).

Jeśli ciąg o wstępnie zdefiniowanej minimalnej długości nie jest potrzebny, spróbuj użyć funkcji IntToStr.

Ponieważ jest to nieodłączne, prawdopodobnie dzieje się coś ekstra. Za kulisami wewnętrzna funkcja jest realizowana przez wywołanie funkcji wsparcia RTL, która daje ShortString. Magia kompilatora zmienia ją w string. I ostrzega cię o niejawnej konwersji. Kompilator magia przemienia

Str(w, s); 

do

s := _Str0Long(w); 

Gdzie _Str0Long jest:

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

Od _Str0Long Zwraca ShortString to kompilator musi generować kod do wykonania niejawny converstion od ShortString do string po przypisaniu do zmiennej s. I oczywiście to jest naturalne, że widzisz W1057.

Najważniejsze jest to, że Str istnieje tylko w celu zachowania zgodności ze starszym kodem Pascal ShortString. Nowy kod nie powinien wywoływać Str. Trzeba robić to, co mówi dokumentacja i nazywają IntToStr:

s := IntToStr(w); 

Albo:

s := w.ToString; 
+0

Przypisanie System.Str do ShortString jest jednym ze sposobów konwertowania liczby całkowitej na tekst bez uderzania w alokację pamięci sterty. –

+0

@LURD True dat. Sądzę, że istnieją lepsze sposoby. W każdym przypadku, tutaj przypiszemy 'string'. Ale dla tych skrajnych przypadków, w których perf ma znaczenie krytyczne, można użyć case'u 'Str'. –

+0

David: pokazałeś mi wielką powściągliwość, nie uwzględniając w swoim wpisie "RTFM". Dziękuję za twoją zwykłą, wyczerpującą odpowiedź. Ponieważ migrujemy ponad milion linii kodu, wybieram trasę "zmień jak najmniej" w tej pierwszej fazie, używając opcji OSTRZEŻEŃ w kilku liniach kodu, które się do tego odwołują. (W rzeczywistości są to Str (w: 3: 1, S), więc dzieje się coś więcej niż prosty przykład, który podałem ... – Tom