2012-04-25 8 views
6

Co próbuję zrobić, to znaleźć wszystkie jawne odlewy z typu double lub float do dowolnego innego typu w niektórych plikach źródłowych, które posiadam. Czy jest to wbudowany sposób GCC, aby to zrobić? Język to C. Dzięki!Czy istnieje sposób na uzyskanie gcc lub clang, aby ostrzec na wyraźnych rzutów?

+2

Może jestem po prostu proste, ale nie można po prostu wyszukać '(podwójna) 'lub' (float) 'w twoim źródle? –

+0

@RobertHarvey Przepraszam, zmieniłem jego brzmienie, aby miało więcej sensu. Chcę przechwycić wszystkie jawne odlewy, które są od typu float/double do czegokolwiek innego, więc mogę wyszukać (int), itp., Ale nie byłbym w stanie stwierdzić, czy są one zmienne czy podwójne. – Chris

+1

Po prostu myśl (nie wiem, C++ lub jeśli jest to nawet możliwe): przesłonę operatora obsady dla podwójnego i zmiennoprzecinkowego, aby wyemitować kompilację i skompiluj jako C++ :) – pmg

Odpowiedz

2

Ponieważ odlewy są wyraźnie prawny i we właściwy sposób wykonywać dziwne konwersji, to jest wysoce prawdopodobne, że gcc będzie zawierać opcję, aby ostrzec o nich

Zamiast tego, w zależności od tego, jak ogromne źródło jest, może być w stanie aby uciec:

grep '\(double|float\) ' * 

aby podać wszystkie zmienne podwójne lub zmiennoprzecinkowe. Ponieważ c nie jest zwykłym językiem, nie jest trywialne (z narzędziami powłoki), aby przeanalizować to na liście zmiennych podwójnych lub zmiennoprzecinkowych, ale jeśli twoje źródło jest wystarczająco małe, zrobienie tego ręcznie jest łatwe.

grep '([^()]*)[()]*\(your list of variable names\)' * 

Stamtąd pokażę ci wiele swoich odlewów.

2

-Wconversion ostrzec za konwersje niejawne, które mogą zmienić wartość (double są duże rodzaju) oraz -Wno-sign-conversion wyłączyć ostrzeżenia o konwersjach między podpisanych i niepodpisanych liczb całkowitych (tak byłoby mniej niepotrzebnych ostrzeżeń). Jeszcze nie widzę żadnej alternatywy standardowego ...

najgorszym przypadku można szuka tych słów kluczowych bezpośrednio do plików źródłowych ...

+1

Z tego co rozumiem, jawne konwersje nie zostaną przechwycone przez -Wkonwersję, w rzeczywistości są sposobem na pozbycie się ostrzeżeń. Zrobiłem kilka testów i okazało się, że jest to prawdą, więc muszę znaleźć inny sposób, aby to zrobić. – Chris

+0

Pechowo, są pokazywane (przynajmniej wtedy, gdy próbowałem kilka miesięcy temu). Włączyłem funkcję "-Wconversion", aby przechwytywać konwersje _accidential__, a ilość szumów generowanych przez jawne (i zamierzone) konwersje była nie do zniesienia. – Damon

0

Dobrze myślę, że nie ma takiej opcji. W końcu ostrzeżenie jest wydawane przez kompilator, aby ostrzec cię przed tym, co zrobiłbyś nieumyślnie. Jednak wyraźna obsada jest w zasadzie sposobem na powiedzenie kompilatorowi "zamknij się, wiem, co robię".

+0

Nie chodzi o to, żeby się unosić, ani dubluć, o co się martwię, to jest z pływającego i podwójnego do czegoś innego. Stworzyłem listę dla wszystkich rzutów, ale muszę wyodrębnić nazwy zmiennych z tej listy, które są tylko zmiennymi lub podwójnymi, co jest bardzo trudne do zrobienia. – Chris

+0

Który typ obsady jest w ogóle problematyczny? Jeśli są problematyczne, dlaczego znaleźli się w kodzie na pierwszym miejscu? –

+1

@cli_hlt: Istnieje zły kod, który musisz naprawić, aby poprawić :) –

6

Jeśli Twój kod C można również skompilować w trybie C++, można użyć flagi ostrzegawczej g ++ 's -Wold-style-cast, aby wyzwolić ostrzeżenie we wszystkich takich rzutach.

Możesz określić, czy Clang ma jakieś ostrzeżenia, które będą powodować określony wzór kodowania przy użyciu jego przełącznika -Weverything (ale pamiętaj, że to nie jest przydatne w prawie każdym innym celu - klang ma wyłączone domyślne ostrzeżenia, które wyzwalają w sprawie różnych form legalnego kodu). Jednak w tym przypadku, klang nie ma żadnych ostrzeżeń, które wyzwalają takie rzuty.

0

Podczas kompilatory wiem nie ma możliwości, że Gimpel za FlexeLint może robić to, co chcesz:

$ cat tst.c 
int main (void) 
{ 
    int i = 0, j = 0; 
    float f = 0.0; 
    double d = 0.0; 

    i = (int) f; 
    j = (int) d; 
    d = (double) f; 
    f = (float) d; 
    i = (int)j; 
    j = (unsigned) i; 
    return (int) j; 
} 

$ flexelint -w1 +e922 tst.c 
FlexeLint for C/C++ (Unix) Vers. 9.00j, Copyright Gimpel Software 1985-2012 

--- Module: tst.c (C) 
       _ 
    i = (int) f; 
tst.c 7 Note 922: cast from float to int 
       _ 
    j = (int) d; 
tst.c 8 Note 922: cast from double to int 
        _ 
    d = (double) f; 
tst.c 9 Note 922: cast from float to double 
       _ 
    f = (float) d; 
tst.c 10 Note 922: cast from double to float 

shell returned 4 
Powiązane problemy