logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

WinAVR jak wyłączyć wyświetlanie Warning'ów

Dr. Kuj 15 Mar 2011 13:59 3178 16
  • #1 9279284
    Dr. Kuj
    Poziom 13  
    Pisze program który ma pare linijek więc podczas kompilacji wyrzuca sporo warningów. Jest ich tak dużo że znalezienie linijki 'error' wśród wszystkich ostrzeżeń jest dosyć uciążliwe. Czy można zrobić coś żeby linijki błędu były wyraźnie zaznaczone albo żeby Warningi wogóle nie były wyświetlane?
    Z tego co do tej pory wyczytałem to trzeba podłubać w makefile w opcjach kompilatora C a dokładniej przy opcji -Wall. Dokładnie nie wiem jak jej użyć bo nie moge znaleźć opisu przełączników (czy co to tam jest..)

    Chyba chodzi o tą część:
    #---------------- Compiler Options C ----------------
    #  -g*:          generate debugging information
    #  -O*:          optimization level
    #  -f...:        tuning, see GCC manual and avr-libc documentation
    #  -Wall...:     warning level
    #  -Wa,...:      tell GCC to pass this to the assembler.
    #    -adhlns...: create assembler listing
    CFLAGS = -g$(DEBUG)
    CFLAGS += $(CDEFS)
    CFLAGS += -O$(OPT)
    CFLAGS += -funsigned-char
    CFLAGS += -funsigned-bitfields
    CFLAGS += -fpack-struct
    CFLAGS += -fshort-enums
    CFLAGS += -Wall
    CFLAGS += -Wstrict-prototypes
    #CFLAGS += -mshort-calls
    #CFLAGS += -fno-unit-at-a-time
    #CFLAGS += -Wundef
    #CFLAGS += -Wunreachable-code
    #CFLAGS += -Wsign-compare
    CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
    CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
    CFLAGS += $(CSTANDARD)


    Mam racje czy źle szukam?
  • #2 9279338
    tmf
    VIP Zasłużony dla elektroda
    Ty się lepiej zastanów dlaczego te warningi masz, bo to jest problem, a nie to jak je wyłączyć. Zapewniam cię, że część tych warningów to pewnie poważne problemy, które prowadzą do błędnego działania programu.
  • #4 9279706
    mirekk36
    Poziom 42  
    Jednym słowem, jeśli dopiero się uczysz - to traktuj warningi jako BŁĘDY i je poprawiaj zamiast wyłączać tych informacji. Bo potem będziesz spędzał o wiele więcej czasu na szukaniu problemów w działaniu procka, będziesz rwał włosy z głowy a może nawet się zniechęcisz do C uznając go za bzdurny język.
  • #5 9280205
    janbernat
    Poziom 38  
    To jeszcze znajdźmy sposób na wywalenie error.
  • #6 9281482
    Dr. Kuj
    Poziom 13  
    heh.. ale żeście pomogli.
    Warningi mają być bo często są to głupoty typu:

    main.c:9081: warning: format '%4.4f' expects type 'double', but argument 3 has type 'float'
    main.c:8774: warning: array subscript has type 'char'

    Program ma 9k linii i jak do tej pory działa idealnie.
    Nie wierze że Wy piszac programy nie macie wogóle ostrzeżeń bo większość rzeczy o które czepia się kompilator to głupotki których eliminacja nie jest konieczna.

    Ponawiam pytanie: Jak w makefile usunąć wyświetlanie ostrzeżeń? (Mniejsza o to że nie jest to dobry pomysł, poprostu jestem ciekaw jak operować samym plikiem makefile)
  • #7 9281601
    mirekk36
    Poziom 42  
    Dr. Kuj napisał:
    heh.. ale żeście pomogli.


    heh... nie chcę być nieuprzejmy, ale odpowiem tym samym, "Ale żeś powidział"

    Dr. Kuj napisał:
    Warningi mają być bo często są to głupoty typu:

    main.c:9081: warning: format '%4.4f' expects type 'double', but argument 3 has type 'float'
    main.c:8774: warning: array subscript has type 'char'


    Po tym widać, że w ogóle nie wiesz co to są warningi i dlaczego się pokazują.

    Dr. Kuj napisał:
    Program ma 9k linii i jak do tej pory działa idealnie.

    A to, że piszesz go niezgodnie z zasadami to już twój problem, brniesz na upartego w bagno - a potem się dziwisz że toniesz i wciąga cię to coraz bardziej.

    Dr. Kuj napisał:
    Nie wierze że Wy piszac programy nie macie wogóle ostrzeżeń bo większość rzeczy o które czepia się kompilator to głupotki których eliminacja nie jest konieczna.


    No to może niech się wypowie chociaż kilka osób, żeby kolega wyrobił sobie nową wiarę.

    Lista:

    1. mirekk36 - w moich programach gdy je kończę nie ma ANI JEDNEGO WARNINGA !!
    2. ....
    3. ....
    4. ....

    kto się jeszcze dopisze ???? tylko obawiam się, że zabraknie papieru na tej liście.

    Dr. Kuj napisał:
    Ponawiam pytanie: Jak w makefile usunąć wyświetlanie ostrzeżeń? (Mniejsza o to że nie jest to dobry pomysł, poprostu jestem ciekaw jak operować samym plikiem makefile)


    Ja nie wiem, wolałem zawsze dowiedzieć się co źle robię gdy widziałem warninga, dlatego teraz wiem jak pisać program żeby się ich pozbywać na bieżąco.

    I nie dziwię się tobie, że ty mając napisane kilka kilo kodu i mając setki warningów jesteś wkurzony..... Tylko masakra polega na tym, że jak mówię skaczesz w przepaść i pytasz się co zrobić żeby to jeszcze przyśpieszyć zamiast jak temu zapobiec ;)
  • #8 9281702
    xE5150
    Poziom 25  
    2. xE5150 - ja również nie mam warningów jak kończę program.

    Widać, że kolega nie ma serca do programowania.

    Pozdrawiam!
  • #9 9281764
    Dr. Kuj
    Poziom 13  
    Trochę mnie załamaliście szczerze powiem... Myślałem że warningi są normą i należy je poprostu pomijać.
    Tymbardziej że kompilator czepia się typu float kiedy powinien być double kiedy typ double jest od dawna nie używany. Co prawda można wyeliminować serie błędów prostym definem na początku ale to trochę bez sensu jak dla mnie..

    W związku z powyższym mam do Was prośbę. Znam angielski trochę ale nie jestem pewien znaczenia wszystkich ostrzeżeń. Jeśli byście mogli to prosze o ich wyjaśnienie:

    (1) warning: "F_CPU" redefined

    Tutaj chodzi o zmianę F_CPU. Kwarc jest określony w makefile, dokładnie:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W swoim programie F_CPU używam do obliczeń baudrate uartu więc musi tu być. Co ciekawe funkcje typue sleep (czekaj określony czas) nie działają kiedy nie wpiszę w swoim kodzie F_CPU=x.
    Przykład:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Inny warn:

    (2) warning: function declaration isn't a prototype

    To przeskakuje do definicji jakiejś tam funkcji. Nie wiem dlaczego się czepia..

    (3) warning: pointer targets in passing argument 1 of 'USART0_Transmit_Word' differ in signedness

    To powoduje przeskok do linijki:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    gdzie:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Czego on tutaj chce?

    (4) warning: conflicting types for 'TSf'

    Powoduje skok do:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    (5) warning: array subscript has type 'char'

    Tutaj kompilator czepia się linii typu:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Co z tego że indeks tablicy jest typu char a nie int? W czym mu to przeszkadza? Przecież nie ma to żadnego znaczenia dla działania programu. Char jest oszczędniejszy niż int dlatego go używam..
    Może przeszkadza mu to że char to signed char a indeks tablicy nie może przyjąć wartości ujemnych? Ale skoro wiem że rozmiar bufora 'tekst' jest mniejszy niż 128 to nie ma się co przejmować, prawda?


    Warningów jest oczywiście więcej ale pochwalę się nimi jeśli ktoś wyjaśni mi te które przedstawiłem. Coś czuję że ten temat będzie przydatny dla potomnych...
  • #10 9281915
    tmf
    VIP Zasłużony dla elektroda
    Traktuj warning jako error. Koniec, kropka. Od tej zasady są tylko nieliczne wyjątki. Inne traktowanie warningów prowadzi do poważnych problemów, a z przykładów, które pokazałeś wynika, że sobie nawet nie zdajesz sprawy do jak poważnych.
    1. warning: "F_CPU" redefined - piekielnie istotny błąd. Gdzieś masz zredefiniowany symbol F_CPU - w efekcie istnieje możliwość, że w różnych miejscach programu ma on różną wartość - katastrofalny efekt dla np. delay łatwo można sobie wyobrazić.
    2. warning: function declaration isn't a prototype - deklaracja funkcji nie jest prototypem. Problem w tym, że nie zdefiniowałeś wymaganych prototypów w pliku nagłówkowym lub prototyp nie jest zgodny z definicją, np. test() i test(void). Piekielnie ważne ostrzeżenie - kompilator potencjalnie może użyć niewłaściwej funkcji.
    3. warning: pointer targets in passing argument 1 of 'USART0_Transmit_Word' differ in signedness - wskaźnik raz jest typu signed, a raz unsigned.
    4. Użyłeś funkcji dla której nie zdefiniowano prototypu. Czyli najpierw odwołujesz się do TSf, a potem ją dopiero definiujesz. W efekcie kompilator tworzy sam, w tym przypadku nieprawidłowy, prototyp. Koszmarnie istotny warning.
    Tak więc, to, że twój program działa poprawnie, o ile tak rzeczywiście jest, to cud. Zagraj w totka, przy takim szczęściu masz parę szóstek z rzędu gwarantowanych :)

    5. warning: array subscript has type 'char' - tu problem jest złożony. Po pierwsze naucz się przekazywać w kodzie to co myślisz. Unikniesz ostrzeżeń. Kompilator nic nie wie o twoich dodatkowych założeniach. Ponieważ char może być signed lub unsigned (w twoim przypadku najwyraźniej jest signed) to potencjalnie indekst tablicy może być ujemny, co w C prowadzi do nieokreślonych efektów. Indeks ten może być ujemny także w wyniku wystąpienia over/underflow, nad czym nie do końca masz kontrolę. Operacje na typach signed są też inne niż na unsigned, np. zastanów się jaka będzie różnica w operacji typ>>1 dla obu wariantów. Stąd też jawnie powinieneś stosować właściwy typ. Drugi powód jest bardziej subtelny - operacje na tablicach, w tym indeksowanie, to operacje arytmetyczne na wskaźnikach. A te w AVR są 16-bitowe, w efekcie nic nie zyskujesz, bo kompilator i tak niejawnie dokonuje promocji typów do int. I to też może być przyczyna warninga.
  • #11 9281983
    Dr. Kuj
    Poziom 13  
    ...ide zagrać w totka......;/




    1. poprawiłem - wszystko działa jak działało bez redefinicji F_CPU. Miałeś racje 'tmf' - to było ważne ostrzeżenie..

    2. function declaration isn't a prototype - już wiem o co chodziło. W definicji miałem np: init_uart() a powinno być init_uart(void).
    Czy funkcja bezparametrowa na pewno wymaga void'a? Z tego co mi się zdaje to nie..
    (A co do różnicy w pliku nagłówkowym a pliku .c to różnicy tej mieć nie moge bo w WinAVR nie pisze się pliku .h osobno. nie wiem jak w innych programach..)

    3. do tego jeszcze wróce...

    4. wiem o co poszło. poprostu funkcje były poprzestawiane miejscami. Aż dziw że działało (ale to chyba tylko pascal wymagał żeby wywoływana funkcja była zawsze wyżej w kodzie...)

    5. wszystkie char zamieniłem na unsigned char i pomogło.

    Lista innych błędów w drodze
  • #12 9282135
    mirekk36
    Poziom 42  
    Dr. Kuj napisał:
    ...ide zagrać w totka......;/


    Zamiast tego po prostu poczytaj jakąś książkę do czystego C - takiego nawet na PC'ty .... poczytaj o typach dokładniej, o rzutowaniu, o wskaźnikach .... bo to jest podstawa podstaw - którą ty jak widać przez długi czas miałeś gdzieś i coś się tam udawało to szedłeś dalej nie oglądając się.

    Tymczasem każda taka książka do standardowego C od razu - Z MARSZU pozwoli ci wyeliminować ze swojego kodu już dziesiątki takich warningów - zobaczysz ;)

    Później sam będziesz się z tego śmiał. Bo to jest proste - tylko trzeba kilka razy czasem przeczytać i RAZ a dobrze zaskoczyć.

    Dodano po 5 [minuty]:

    Podam ci przykład takiego pisania błędnego programu z warningami, który niby nie powinien nawet działać a działa:


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    to jest podkreślam totalna BZDURA ;) .... kompilator sypie warningami - ale na LCD pojawia się napis "HELLO WORLD";

    oczywiście nie zawsze się on pojawi i nie w każdych warunkach - ale początkującą osobę to może bardzo zmylić a wręcz doprowadzić do przekonania, że można w ogóle w C zrobić takie działanie:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Mam nadzieję, że to będzie dla ciebie przykład dlaczego tobie nieraz coś działało pomimo warningów a jednak było to robione wbrew zasadom i logice .... i prowadziło do szaleństwa ;)
  • #13 9282151
    Dr. Kuj
    Poziom 13  
    Przykład podałeś dobry ale zapewniam że nigdy nie dokonałem operacji przypisania na statycznym łańcuchu bo taka nie ma sensu. W C trzeba to robić za pomocą strcpy itp.

    Mam pytania dotyczące kolejnych warningów:

    (6) warning: array subscript is above array bounds

    Ten jak rozumiem dotyczy przekroczenia zakresu tablicy co w takiej funkcji:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    wcale nie musi się wydarzyć.. Dlaczego więc kompilator zakłada że zakres jest przekroczony?
    (wiem że ta funkcja jest debilna i niebezpieczna, spokojnie - nie używam jej, robi tylko za przykład)

    (7) warning: extra tokens at end of #endif directive

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zakładam że coś tam jest nieprawidłowo dokładane, czego powinienem szukać? co mu może przeszkadzać?

    (8) warning: passing argument 1 of 'strncmp_P' discards qualifiers from pointer target type


    Czepia się tego:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    O co tutaj może mu chodzić?

    (9) warning: useless storage class specifier in empty declaration

    To dotyczy deklaracji typu zmiennej:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Najprawdopodobniej nie rozumiem do końca działania typedef i zaraz to doczytam ;/

    (10) warning: 'return' with a value, in function returning void

    To akurat wiem co oznacza ale zastanawia mnie czy zwrócenie jakiejś wartości przez void'ową funkcje może jakoś zaszkodzić pracy programu?

    (11) warning: incompatible implicit declaration of built-in function 'sprintf'oraz warning: implicit declaration of function 'toupper'

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Na to nie mam pomysłu bo sprintf działa jak należy...

    (12) warning: "/*" within comment

    Komentarz w komentarzu.. Czy to grozi jakąś katastrofą?

    (13) warning: return type of 'main' is not 'int'

    Podobnie to: przecież kompletnie nie ma znaczenia co zwraca main(). Return z maina oznacza koniec pracy programu a tego się nigdy nie robi. Mam wrażenie że kompilator się czepia żeby czepiać i ma to sens jeśli piszemy na PC a nie na uC. pozatym często spotykam się z zapisem

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Który wydaje mi się jak najbardzie poprawny. Co o tym sądzicie? Mylę się?
  • #14 9282327
    dondu
    Moderator na urlopie...
    Dr. Kuj napisał:
    Nie wierze że Wy piszac programy nie macie wogóle ostrzeżeń ...

    Słabej wiary jesteś :D


    Dr. Kuj napisał:
    1. poprawiłem ... Miałeś racje 'tmf' - to było ważne ostrzeżenie..

    I to właśnie chcemy Ci wpoić - warning może być w konsekwencji poważnym błędem.

    Dodano po 12 [minuty]:

    Dr. Kuj napisał:
    To akurat wiem co oznacza ale zastanawia mnie czy zwrócenie jakiejś wartości przez void'ową funkcje może jakoś zaszkodzić pracy programu?

    Rolą warningów generowanych przez kompilator jest pokazywanie użytkownikowi jakie ma potencjalne miejsca powstawania błędów. I działa to tak, że gdyby kompilator nich nie pokazywał, to w przypadku nieprawidłowego działania programu rwałbyś włosy z głowy, bo uważałbyś, że wszystko jest OK, czego przykładem niech będzie:

    Dr. Kuj napisał:
    wcale nie musi się wydarzyć.. Dlaczego więc kompilator zakłada że zakres jest przekroczony?
  • Pomocny post
    #15 9282610
    mirekk36
    Poziom 42  
    6 - każdą (debilną) funkcję jak ją nazwałeś da radę przerobić na normalną

    7 - szukaj błędu po #endif zgodnie z komunikatem a nie wewnątrz warunku

    8 - naucz się rzutowania typów bo w tym przypadku specyfikator volatile nieco zmienia traktowanie zmiennej slowo0. Poza tym jak używasz jakiegoś srodowiska, które domyślnie zamienia unsigned char na char - to nie stosuj tego unsigned, takie coś już przejdzie bez warningów i będzie prawidłowo:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    9 - dokładnie (czyli dobrze myślisz ;) ) - doczytaj o definiowaniu struktur i posługiwaniu się typedef a wszystko ładnie ruszy

    10 - a po co ci się zastanawiać i robić coś co i tak wiesz że nie powinno być - w tym przypadku dodawać return do funkcji która zwraca void. To tak jakbyś siedział na gałęzi i ją sobie podcinał - a gdy spadniesz to dziwił się dlaczego tak się stało? - No nie zaszkodzi - bo kompilator sobie z tym poradzi ale grzecznie ci podpowiada że głupoty piszesz więc co? sam masz warningi na własne życzenie bo lubisz drażnić się z kompilatorem ? ;)

    11 - tutaj na szybko nie odpowiem teraz

    12 - patrz pkt 10 ;) A dodam, że wbrew pozorom komentarze dobry programista traktuje wręcz jak kod programu

    13 - no to poczytaj sobie o standardzie i dlaczego jest taka histroyczna zaszłość - znowu patrz pkt. 10 .... i jak lubisz zawsze coś robić na odwrót to rób - wg mnie bez sensu jest takie działanie. Co za problem wpisać

    int main(void) ???
  • Pomocny post
    #16 9282744
    tmf
    VIP Zasłużony dla elektroda
    Dr. Kuj napisał:

    2. function declaration isn't a prototype - już wiem o co chodziło. W definicji miałem np: init_uart() a powinno być init_uart(void).
    Czy funkcja bezparametrowa na pewno wymaga void'a? Z tego co mi się zdaje to nie..
    (A co do różnicy w pliku nagłówkowym a pliku .c to różnicy tej mieć nie moge bo w WinAVR nie pisze się pliku .h osobno. nie wiem jak w innych programach..)

    4. wiem o co poszło. poprostu funkcje były poprzestawiane miejscami. Aż dziw że działało (ale to chyba tylko pascal wymagał żeby wywoływana funkcja była zawsze wyżej w kodzie...)



    2. Funkcja test() i test(void) to dwie różne funkcje. test(void) to funkcja, która nie ma argumentów, a test() to funkcja, która ma nieokreślone argumenty, czaisz różnicę?
    Co do nagłóków, co znaczy, że w WinAVR nie pisze się osobno? Znaczy, że ty nie piszesz? To robisz poważny błąd.
    4. C też tego wymaga, inaczej przyjmuje domyślny prototyp, zwykle błędny. Stąd też konieczność stosowania nagłówków i deklaracji.

    Dodano po 4 [minuty]:

    10. Nie zaszkodzi, bo optymalizator to i tak wywali, ale jest bez sensu i wprowadza w błąd osobę przeglądającą kod.
    11. Nie inkludujesz zapewne nagłówka posiadającego prototyp funkcji sprintf. A że jej ciało jest w linkowanej bibliotece standardowej, to linkowanie jest ok, tylko znowu brak prototypu.
    13. Napisz int main i już. Jest tak, bo zakończenie programu w systemie z OS to nie zakończenie funkcjonowania OS. Jak dasz int to się nic nie stanie i kodu ci to też nie wydłuży.
  • #17 9283275
    Dr. Kuj
    Poziom 13  
    (11) warning: incompatible implicit declaration of built-in function 'sprintf'oraz warning: implicit declaration of function 'toupper'

    Rozwiązanie:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Mam jeszcze kilka zastanawiających warningów:

    (14) warning: conflicting types for 'StringCpy'


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Gdzie kompilator widzi tutaj konflikt typów? Nawet jeśli zakomentuje ciało funkcje to pojawia się to ostrzeżenie - nie czepia się więc tego co w środku.
REKLAMA