Forum: Compiler & IDEs lwip: ip_addr_isany gcc warnung


von pegel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte lwip auf dem stm32f7 nutzen und möglichst ohne Warnung 
compilieren.

Um das Problem zu lösen habe ich das gefunden:
in der ip_addr.h füge ich ein (void*) ein und es gibt keine Warnung 
mehr.
1
#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY)
wird zu
1
#define ip_addr_isany(addr1) ((void*)(addr1) == NULL || (addr1)->addr == IPADDR_ANY)

Jetzt verstehe ich aber nicht genau was da passiert.
Wird die ganze Funktion nicht durch das void zerstört bzw ausgehebelt?

von Mikro 7. (mikro77)


Lesenswert?

Du hast wohl eine Adresse als Argument verwendet. Der Compiler fragt 
sich nun warum "du" diese mit NULL vergleichst, was niemals wahr sein 
kann.

Nach dem (void*) cast fragt der Compiler nicht mehr nach weil du ihm 
sagst, dass du weißt was du tust. Kann man so machen.

Das Makro scheint kein Standard zu sein. Ich würde daher drauf 
verzichten. Also statt
1
ip_addr_isany(&current_iphdr_src)

direkt das Feld vergleichen
1
current_iphdr_src.addr == IPADDR_ANY

von pegel (Gast)


Lesenswert?

Danke für die Antwort.
Hast schon Recht, "ich" habe nicht viel gemacht. Das hat CubeMX für mich 
getan ;)

Meine Unklarheit ist dabei direkt das (void*).
Macht das nicht aus dem was danach kommt immer NULL und nix, egal welche 
Variable von welchen Typ dann in den Klammern folgt?
Somit wäre dann der Vergleich == NULL immer erfüllt?!

Oder verstehe ich das total falsch?

von Mikro 7. (mikro77)


Lesenswert?

> Meine Unklarheit ist dabei direkt das (void*).
> Macht das nicht aus dem was danach kommt immer NULL und nix, egal welche
> Variable von welchen Typ dann in den Klammern folgt?

Nein. Es macht aus den typisierten Pointer einen untypisierten Pointer. 
Der Wert bleibt der selbe.

> Somit wäre dann der Vergleich == NULL immer erfüllt?!

Ich nehme an, dass du eine Adresse übergibst. Diese kann niemals NULL 
sein (der Vergleich ist also niemals erfüllt). Bsp.
1
#include <stdio.h>
2
3
int main()
4
{
5
  int i = 0 ;
6
7
  if (        &i  != NULL) printf("As expected (1)\n") ;
8
  if ((void*)(&i) != NULL) printf("As expected (2)\n") ;
9
10
  return 0 ;
11
}
1
prompt>gcc -Wall -o test test.c
2
test.c: In function ‘main’:
3
test.c:7:19: warning: the comparison will always evaluate as ‘true’ for the address of ‘i’ will never be NULL [-Waddress]
4
   if (        &i  != NULL) printf("As expected (1)\n") ;
1
 
2
prompt> ./test
3
As expected (1)
4
As expected (2)

von pegel (Gast)


Lesenswert?

Ahhh.

Vielen Dank!
Ich glaube jetzt hab ichs!

von Rolf Magnus (Gast)


Lesenswert?

Mikro 7. schrieb:
> Ich nehme an, dass du eine Adresse übergibst. Diese kann niemals NULL
> sein (der Vergleich ist also niemals erfüllt).

Ich frage mich nur, warum das jetzt irgendwie schlimm sein und eine 
Warnung erfordern müßte. Oder warum ein Cast nach void* daran irgendwas 
ändern würde.

von Sven B. (scummos)


Lesenswert?

Rolf Magnus schrieb:
> Ich frage mich nur, warum das jetzt irgendwie schlimm sein und eine
> Warnung erfordern müßte.
Weil eine Bedingung die immer oder nie erfüllt ist meist nicht das ist 
was du schreiben wolltest. Darauf weist die Warnung hin.

von Mikro 7. (mikro77)


Lesenswert?

Rolf Magnus schrieb:
> Mikro 7. schrieb:
>> Ich nehme an, dass du eine Adresse übergibst. Diese kann niemals NULL
>> sein (der Vergleich ist also niemals erfüllt).
>
> Ich frage mich nur, warum das jetzt irgendwie schlimm sein und eine

Nicht schlimm. Daher nur eine Warnung. Ich habe schon Programmcode 
gesehen mit mehreren hundert Zeilen nach einer solchen Verzweigung. 
-Wall ist dein Freund. ;-)

> Warnung erfordern müßte. Oder warum ein Cast nach void* daran irgendwas
> ändern würde.

Dass der Cast das auflöst finde ich auch überraschend. Vielleicht ein 
gcc Hack? Oder gcc sieht es nach dem Cast tatsächlich nicht mehr... Bis 
zur nächsten verbesserten Version, wo es dann vielleicht wieder als 
Warnung auftaucht.

von Rolf Magnus (Gast)


Lesenswert?

Mikro 7. schrieb:
> Rolf Magnus schrieb:
>> Mikro 7. schrieb:
>>> Ich nehme an, dass du eine Adresse übergibst. Diese kann niemals NULL
>>> sein (der Vergleich ist also niemals erfüllt).
>>
>> Ich frage mich nur, warum das jetzt irgendwie schlimm sein und eine
>
> Nicht schlimm. Daher nur eine Warnung.

Nunja, meist will man ja doch, dass der Code ohne Warnungen durchläuft. 
In dem Sinne ist eine Warnung dann auch schlimm.

> Ich habe schon Programmcode gesehen mit mehreren hundert Zeilen nach
> einer solchen Verzweigung.

Der Compiler sieht ja offenbar darüber hinaus. Es ist nicht einfach die 
Warnung, dass das Ergebnis zur Compilezeit feststeht, sondern ganz 
spezifisch, dass der Zeiger nie NULL sein kann. Ein Makro wie das obige 
finde ich nicht so ungewöhnlich, und es ist ja auch korrekt und 
funktioniert auch fehlerfrei. Da ist es ärgerlich, wenn der Compiler da 
auf einmal warnt.

> -Wall ist dein Freund. ;-)

Unter -std=C99 -pedantic -Wall -Wextra geht bei mir nix :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.