Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Ostrzeżenie w czasi kompilacji, o co chodzi?

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Ostrzeżenie w czasi kompilacji, o co chodzi?

Postautor: Sławek5 » 6 gru 2006, o 13:40

Mam taki fragment kodu w C

Kod: Zaznacz cały

char i,j; st[3]=0; for(i=2;i>=0;i--) st[i]=st[j];
Jest to tylko fragment aby nie zamazć, ale podczas kompilacji jest ostrzeżenie
warning: subscript has type `char'


Jak zmienię na unsigned char i,j; To dostaję jeszzce inny komunikat
warning: comparison is always true due to limited range of data type


Wskazując na linię

Kod: Zaznacz cały

for(i=2;i>=0;i--)
A następny fragment kodu to

Kod: Zaznacz cały

Lcd_write_rom(PSTR("Wait..."));
I ostrzeżenie warning: passing arg 1 of `Lcd_write_rom' discards qualifiers from pointer target type

Dodam że to powyżej jest napisane w starszej wersji AVR-GCC natomiast ja teraz robię kompilacje w najnowszej, może dlatego, ale jak to naprawić?

Awatar użytkownika
bis
-
-
Posty: 134
Rejestracja: 12 maja 2005, o 08:11
Lokalizacja: Warszawa

Postautor: bis » 6 gru 2006, o 15:31

Jak zmienię na unsigned char i,j; To dostaję jeszzce inny komunikat
warning: comparison is always true due to limited range of data type


Wskazując na linię
Kod:
for(i=2;i>=0;i--)
no jeżeli zadeklarowałeś że i należy do zbioru liczb [255..0] to jaka będzie wartość wyrażenia i>=0 dla dowolnej wartości jaką może przyjąć i?

Pozostałe komunikaty są juz specyficzne dla danej implementacji C i jego bibliotek. Pierwszy prawdopodobnie ostrzega o domyślnej zmianie typu indeksu, ostatni dotyczy utraty rozróżnienia pomiędzu wskażnikami (w małych prockach wskażnik do zmiennej w RAM nie musi byc kompatybilny ze wskażnikiem do kodu, w różnych kompilatorach różnie sobie z tym radzą). Ale tu to już gdybam bo nie używałem takiego kompilatora.
bis

radzio
Moderator
Moderator
Posty: 965
Rejestracja: 13 maja 2003, o 10:33
Lokalizacja: Sosnowiec
Kontaktowanie:

Re: Ostrzeżenie w czasi kompilacji, o co chodzi?

Postautor: radzio » 6 gru 2006, o 15:37

warning: subscript has type `char'
Tablica nie może mieć ujemnego indeksu, a w przypadku typu char taka sytuacja może zaistnieć
warning: comparison is always true due to limited range of data type

Wskazując na linię

Kod: Zaznacz cały

for(i=2;i>=0;i--)
Tutaj zaś warunek pętli for (i>=0) będzie zawsze spełniony z uwagi na typ unsigned, który nigdy nie osiągnie wartości ujemnej,

Kod: Zaznacz cały

Lcd_write_rom(PSTR("Wait..."));
I ostrzeżenie warning: passing arg 1 of `Lcd_write_rom' discards qualifiers from pointer target type

Kod: Zaznacz cały

Lcd_write_rom((char *)PSTR("Wait..."));

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 6 gru 2006, o 16:24

Faktycznie :oops:
A ja się zastanawiałem o jaki index dolny kompilatorowi chodzi? A to liczby ujemne.

Ale niby kompilator daje ostrzeżenie ze warunek jest zawsze prawdziwy to i tak pętla bedzie wukonywana 3 razy.

A jest jakiś sposób aby komilator nie generował tych ostrzeżeń.

Awatar użytkownika
bis
-
-
Posty: 134
Rejestracja: 12 maja 2005, o 08:11
Lokalizacja: Warszawa

Postautor: bis » 6 gru 2006, o 16:31

Ale niby kompilator daje ostrzeżenie ze warunek jest zawsze prawdziwy to i tak pętla bedzie wukonywana 3 razy.
Czy aby na pewno?
A jest jakiś sposób aby komilator nie generował tych ostrzeżeń.
To już Radzio pokazał, odpowiednie rzutowania.

bis

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Re: Ostrzeżenie w czasi kompilacji, o co chodzi?

Postautor: a_antoniak » 6 gru 2006, o 17:33

warning: subscript has type `char'
Tablica nie może mieć ujemnego indeksu, a w przypadku typu char taka sytuacja może zaistnieć
Na upartego mozna uzywac indeksow ujemnych w tablicach, choc zwykle sie tego nie robi.

Kod: Zaznacz cały

char Tab[]={1,2,3}; char *pcTmp = NULL; pcTmp = Tab + 1; printf("%d",pcTmp[-1]);
Wypisze "1".

W ten sposob mozna sprawdzic, ile bajtow przydzielil malloc, majac dany tylko wskaznik przezen zwrocony. Funkcja free "wie" ile bajtow zwolnic, bo ich liczba zapisywana jest przed pierwszym przydzielonym bajtem (a wiec z indeksem ujemnym, jesli potraktowac ciag przydzielonych bajtow jako tablice) :).
Ale niby kompilator daje ostrzeżenie ze warunek jest zawsze prawdziwy to i tak pętla bedzie wukonywana 3 razy.
"troche" wiecej razy, tak ok. nieskonczonosc (tzn. do resetu) :).

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 6 gru 2006, o 19:18

Czyli ta pętla jest błędna?
Tzn. z unsigned char nie wykona się 3 razy, a z char będzie ostrzeżenie ale za to wykona się 3 razy.
To jest dla mnie coś nowego (nie spotkałem się z tym wcześniej) i jak zwykle sie zamieszałem. To co z tym zrobić? Aby było dobrze i bez ostrzeżeń.

radzio
Moderator
Moderator
Posty: 965
Rejestracja: 13 maja 2003, o 10:33
Lokalizacja: Sosnowiec
Kontaktowanie:

Postautor: radzio » 6 gru 2006, o 21:10

No to może tak:

Kod: Zaznacz cały

unsigned char i,j; st[3]=0; for(i=3;i>0;i--) st[i-1]=st[j];

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 7 gru 2006, o 06:11

Cześć

Chyba "wsadzę kij w mrowisko" ale poruszę jeszcze taką rzecz.

Jeżeli mam funkcję:

Kod: Zaznacz cały

void print(prog_char* str) { char znak; while( 0 != (znak = pgm_read_byte(str++)) ) LCDdata(znak); }
Która wyswietla na LCD stałe tekstowe, to wywołanie jej w postaci:

Kod: Zaznacz cały

print(PSTR("Lancuch z FLASHa"))

Generuje ostrzeżenie
warning: passing arg 1 of `print' discards qualifiers from pointer target type


Pomaga rzutowanie

Kod: Zaznacz cały

print((prog_char*)PSTR("Lancuch z FLASHa"));
Tylko dlaczego skoro makro PSTR zwraca wskażnik do obszaru Flash, który jest akceptowalny przez funkcję. Dlaczego rzutownie, skoro funkcja print przyjmuje wskaźnik prog_char *


P.S.
Sprawdziłem też taką sytuację

Kod: Zaznacz cały

prog_char g_napispgm[] = "Lancuch ";
i wywołanie

Kod: Zaznacz cały

print(g_napispgm)

I niezależnie czy funkcja jest zadeklarowania jako void print(char *ptr) czy jako void print(prog_char *ptr) to też jest ten sam komunikat

Jurek Szczesiul
-
-
Posty: 175
Rejestracja: 10 paź 2003, o 20:44
Lokalizacja: Białystok
Kontaktowanie:

Postautor: Jurek Szczesiul » 9 gru 2006, o 16:11

[quote="Sławek5"]
Jeżeli mam funkcję:

Kod: Zaznacz cały

void print(prog_char* str) { char znak; while( 0 != (znak = pgm_read_byte(str++)) ) LCDdata(znak); }
Która wyswietla na LCD stałe tekstowe, to wywołanie jej w postaci:

Kod: Zaznacz cały

print(PSTR("Lancuch z FLASHa"))
Generuje ostrzeżenie
warning: passing arg 1 of `print' discards qualifiers from pointer target type

Pomaga rzutowanie

Kod: Zaznacz cały

print((prog_char*)PSTR("Lancuch z FLASHa"));
Tylko dlaczego skoro makro PSTR zwraca wskażnik do obszaru Flash, który jest akceptowalny przez funkcję. Dlaczego rzutownie, skoro funkcja print przyjmuje wskaźnik prog_char *

Radosław juz powyjaśniał na EdW. Ja tylko dodam, że IMHO nie warto
aż tak dociekać _dlaczego_ avr-gcc robi coś tak czy owak. To ciągle
rozwijane narzędzie i mogą występować zmiany. Np. powyższe
ostrzeżenia występują w gcc3.4.4 a w 4.1.1 już nie. Ważne co Ty chcesz
osiągnąć i odpowiednimi rzutowaniami w razie potrzeby dopasowujesz się
do wymogów kompilatora.

Pozdrowienia Jurek S.

Wróć do „AVR/AVR32”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 33 gości