Nie mogę znaleźć źródeł SetLength - w jakim pliku je znajdę?
Nie znajdziesz go, dlatego że jest to pseudoprocedura, której kod generowany jest w locie podczas kompilacji. Jej działanie jest różne dla różnych elementów języka – ogólnie sprowadza się do (re)alokacji bloku oraz zaktualizowania metadanych (długość, licznik referencji, strona kodowa itd.).
Niestety analizator kodu Lazarusa nie radzi sobie z detekcją, że w dalszej części kodu jest tablica/łańcuch wypełniona.
A jak jest w Delphi? FPC co nieco wykryć potrafi, ale cudów nie należy się spodziewać, bo taka skrupulatność negatywnie odbiła by się na czasie kompilacji. Gdybyś miał jawną pętlę iterującą po wszystkich znakach ciągu, to pewnie by tego hinta nie było.
Patrząc na tworzenie kody w zespole, powinno stosować się bezpieczne i powszechnie używane rzeczy.
I jedną z nich jest FillChar
, rzadziej można spotkać ZeroMemory
(bo stricte windowsowe), ale się zdarza. :)
Sądzę, że to niezalecanie array of char, jest w sprawie używania tego jako łańcuchów reprezentujących tekst, do składania komunikatów etc.
Dokładnie o tym jest ta wzmianka w wiki. Tablice znaków były używane 40 lat temu, kiedy język nie posiadał konkretnego typu do reprezentowania ciągów (czyli ShortString
na początku, później String
i kupa innych).
Czyli on nadal hinty jakoś klasyfikuje, ukrył hint o SetLength ale zostawił np. o nieużywanych zmiennych. Fajna opcja, dzięki.
Nom – komunikaty kompilacji mają swoje ”wagi”. Niektóre będą zawsze widoczne, niektóre tylko przy słabszym filtrowaniu, bo dotyczą pierdół lub rzeczy dotyczących internalsów biblioteki standardowej i/lub funkcjonalności kompilatora. Jednym z nich jest np. ten:
Hint: "inherited" not yet supported inside inline procedure/function
Pojawia się ich kilkaset przy wyłączonym filtrowaniu w moim projekcie CTCT. Nie posiadają numeru linii i modułu źródłowego, nie da się dwuklikiem przejść do linii, której dotyczą. Nie wiadomo skąd się biorą i czego dotyczą – pojawiają się nie z mojej winy.
Obstawiam, że gdzieś głęboko w internalsach stdliba ktoś użył inherited
w inline
'owanej rutynce w którejś metodzie którejś bazowej klasy, a że kompilator takiej konstrukcji nie wspiera to teraz za każdym razem gdy używam jakichś klas, to ten hint wyłazi. Jedyne co można z nim zrobić to odfiltrować, bo ma niską wagę.
Może 10 lat temu, ale dziś to raczej powinien użyć TDictionary<string, class>
a w FPC może bardziej TFPObjectHashTable
; nie wiem, nie znam się na FPC.
W module FPG
jest generyczna klasa TFPGMapObject
– powinna pasować do wymagań. Używam jej np. do przechowywania par łańcuch-obraz w takiej postaci:
type
TFlagsMap = class(specialize TFPGMapObject<String, TPortableNetworkGraphic>)
{..}
Kluczem jest nazwa państwa, a na wyjściu dostaję obraz tła. Wygodne, bo nie dość że łatwo pobrać interesujący obraz, to pamięcią obiektów zarządza klasa, więc dealokacją się nie przejmuję.
W FPC nie można ostrzeżeń wyłączyć tylko dla danego kawałka kodu?
Można, można. Wszystkie kompilatory Pascala obsługują np. {$HINTS OFF/ON}
i inne, którymi można wykluczyć generowanie komunikatów dla zadanych fragmentów. Jest jeszcze makro {%H-}
, ale to jest dyrektywa IDE, która pozwala ukryć dany hint w oknie komunikatów kompilacji, choć nadal będzie on generowany.
Dla wyjaśnienia – frazy z prefiksem {$
to dyrektywy kompilatora, a z {%
to makra IDE.
W tym jednym przypadku uważam, za nadmiarowe, gdzie linijkę niżej wypełniam cały łańcuch.
Jeśli zawsze wypełniasz cały łańcuch to zignoruj ten hint – wyklucz go i z głowy.
Jak ktoś ma komfort używania nowszych Delphi to używa TDictionary ;) Zgodzę się, jest to lepsze.
Rozglądnij się po modułach dla FPC – znajdziesz w nich różne generyczne kontenery. W razie czego możesz też dociągnąć sobie bibliotekę Generics.Collections, w której znajduje się dużo więcej klas.