warning: passing arg 1 of `print' from incompatible pointer type
.
Wenn ich den ersten const (oben markiert) entfernt passt alles.
Warum? Das Argument Liste ist ein Array bzw. ein konstanter Pointer auf
einige Einträge. Jeder dieser Einträge ist ein String, also ein
Char-Array und somit ein weiterer Pointer. Der Inhalt vom Char-Array ist
nicht konstant, der Pointer auf das Array schon, also 2 mal const. Wo
ist mein Denkfehler?
Problem 2:
1
//aufs strikte Minimum reduziert
2
#include<stdio.h>
3
#include<stdlib.h>
4
#include<inttypes.h>
5
6
uint32_tNbDateien=0;//jaja ich weiß, globale Variablen sind ganz böse... ;-)
if(PosAuswahl+OffsetAnzeige-2<NbDateien)//WARNUNG FÜR DIESE ZEILE
22
{
23
//tu was anderes
24
}
25
//...
26
}
27
28
return0;
29
}
Diesmal beschwert sich der GCC
1
warning: comparison between signed and unsigned
. Google liefert Codefetzen welche signed-Variablen enthalten, das ist
bei mir nicht der Fall. PosAuswahl+OffsetAnzeige-2 ist bei mir doch
immer >=0 weil die if-Abfrage nur ausgeführt wird wenn die übergeordnete
wahr ist und diese Übergeordnete testet ja ob
PosAuswahl+OffsetAnzeige>=2. Was ist da los?
GCC wird mit -Wall und -Wextra aufgerufen, Version 3.4.5 unter Windows.
0 + 0 - 2 ist aber negativ.
Und der Compiler prüft nicht, ob du semantisch in die erste if-Abfrage
gehst. Für den Compiler kann da -2 rauskommen. Und das meckert er -
zurecht - an.
Lord Ziu schrieb:> 0 + 0 - 2 ist aber negativ.>> Und der Compiler prüft nicht, ob du semantisch in die erste if-Abfrage> gehst. Für den Compiler kann da -2 rauskommen. Und das meckert er -> zurecht - an.
Du hast Recht das der Compiler die erste if-Abfrage nicht semantisch
analysiert. Allerdings werden auch keine Wertebereich betrachtet. So ist
das Ergebnis einer Differenz-Operation durchaus unsigned, wenn beide
Operanden unsigned sind.
Das Problem ist, das '2' eine Konstante vom Typ 'int' ist. Der Ausdruck
"PosAuswahl + OffsetAnzeige" hat den Typ uint8_t. Der Compiler fuegt
einen impliziten Cast auf 'int' ein, denn er kann immer nur gleiche
Typen verknuepfen. Dafuer gibt es komplexe Regeln, im Prinzip wird aber
immer auf den allgemeineren bzw. breiteren Typ gecastet - hier also
'int'.
Wenn Du statt '2' eine unsigned Konstante verwendest, also '2U' sollte
die Warning weg sein !
Strings der Länge 2 sind ziemlich witzlos, zumindest, wenn die Länge
statisch ist.
Anponsten ist der Fehler warhsceinlich, dass du schreiben müsstest.
print(&ListeLaufwerke);
Kai S. schrieb:> Wenn Du statt '2' eine unsigned Konstante verwendest, also '2U' sollte> die Warning weg sein !
Stimmt!
> Das Problem ist, das '2' eine Konstante vom Typ 'int' ist. Der Ausdruck> "PosAuswahl + OffsetAnzeige" hat den Typ uint8_t. Der Compiler fuegt> einen impliziten Cast auf 'int' ein, denn er kann immer nur gleiche> Typen verknuepfen. Dafuer gibt es komplexe Regeln, im Prinzip wird aber> immer auf den allgemeineren bzw. breiteren Typ gecastet - hier also> 'int'.
Okay... '2' ist also vom Typ signed int, d.h. der Compiler castet den
linken Teil vom Ausdruck auf signed int und meckert dann weil der rechte
Teil unsigned ist, richtig?
Ich hab das mal ausprobiert:
funktioniert nur richtig wenn der linke Teil positiv ist. Wenn ich "2U"
schreibe entfällt zwar die Warnung aber es geht trotzdem nicht, erst
wenn ich NbDateien auf signed caste passt alles. Interessanterweise
reicht ein (signed) ohne Angabe eines Datentypes. Die Warnung ist also
(wie fast alle anderen) sehr ernst zu nehmen.
Solange mindestens einer der beiden Ausdrücke unsigned ist betrachtet
der Compiler das MSB als "normales Bit" und nicht als Vorzeichen, was im
oberen Fall natürlich Chaos ergibt. Nur wenn keiner der Ausdrücke
erwiesenermaßen negativ werden kann darf man die Warnung durch ein 'U'
unterdrücken (ohne Cast). Sehe ich das richtig?
Puh, ich glaube ich werde diese Sprache nie richtig verstehen. :-( (Und
bevor Karl-Heinz ankommt, den K&R habe ich schon, hat auch schon oft
geholfen. ;-) )
Vlad Tepesch schrieb:> Was spricht eigentlich gegen folgendes:> [...]> Strings der Länge 2 sind ziemlich witzlos, zumindest, wenn die Länge> statisch ist.
Compiler haben eh sehr wenig Humor (kleiner Scherz am Rande). Mal
ernsthaft: Ich habe noch einige weitere Listen welche alle aus Strings
(Länge>>2) bestehen und will konsistent bleiben (überall Strings).
> Anponsten ist der Fehler warhsceinlich, dass du schreiben müsstest.> print(&ListeLaufwerke);
Huh? ListeLaufwerke ist (in diesem Kontext) doch bereits ein Pointer auf
das erste Array-Element oder? Ich habs gerade ausprobiert, bei
"&ListeLaufwerke" meckert der Compiler immer, egal ob 0,1 oder 2 const.
Funktionieren tuts trotzdem. -->Hä?!?
Vlad Tepesch schrieb:> nebenbei:> üblich ist:> Typen mit großem Anfangsbuchstaben,> instanzen kleiner Anfangsbuchstaben
Du meinst
1
typedefcharTyp_t[42];
2
Typ_tinstanz;
? Danke für den Hinweis, das mit den Bezeichnern ist bei mir eh so eine
Sache. Meistens nutze ich einen gräßlichen Deutsch-Englisch-Mix.
Deutsche Wörter mit Kleinbuchstaben am Anfang kann ich irgendwie nicht
leiden.
Danke euch erstmal, für heute hab ich genug.
Zitroneneis schrieb:> Solange mindestens einer der beiden Ausdrücke unsigned ist betrachtet> der Compiler das MSB als "normales Bit" und nicht als Vorzeichen,
Nein, so einfach ist es nicht. Es wird (verfeinfacht gesagt) auf den
'größeren' der beiden Typen gecastet und der kann durchaus
vorzeichenbehaftet sein.
Eine andere Lösung für Dich könnte folgendes sein:
So, da bin ich wieder.
... schrieb:> Zitroneneis schrieb:>> Solange mindestens einer der beiden Ausdrücke unsigned ist betrachtet>> der Compiler das MSB als "normales Bit" und nicht als Vorzeichen,>> Nein, so einfach ist es nicht. Es wird (verfeinfacht gesagt) auf den> 'größeren' der beiden Typen gecastet und der kann durchaus> vorzeichenbehaftet sein.
OK, hab noch mal im K&R nachgelesen und hoffe es jetzt verstanden zu
haben, ansonsten melde ich mich wieder. Diese
integer-promotion-Geschichten sind ganz schön kompliziert. :-(
> Eine andere Lösung für Dich könnte folgendes sein:>
1
>if(PosAuswahl+OffsetAnzeige<NbDateien+2)
2
>...
3
>
Stimmt... Im Kontext kann ... -2U < ... aber deutlicher bzw.
offensichtlicher sein, dann nutze ich lieber diese Möglichkeit.
Was ich aber nicht verstehe ist das hier:
> Vlad Tepesch schrieb:>> Anponsten ist der Fehler warhsceinlich, dass du schreiben müsstest.>> print(&ListeLaufwerke);> Huh? ListeLaufwerke ist (in diesem Kontext) doch bereits ein Pointer auf> das erste Array-Element oder? Ich habs gerade ausprobiert, bei> "&ListeLaufwerke" meckert der Compiler immer, egal ob 0,1 oder 2 const.> Funktionieren tuts trotzdem. -->Hä?!?
Warum funktioniert das auch wenn man die Adresse von ListeLaufwerke
(das ist ein schon Pointer) übergibt?
Hat jemand eine Idee was es mit der ersten Warnung auf sich hat?
Zitroneneis schrieb:> Problem 1:>
1
>//aufs strikte Minimum reduziert
2
>#include<stdio.h>
3
>#include<stdlib.h>
4
>#include<inttypes.h>
5
>#defineNB_LAUFWERKE_MAX16
6
>
7
>typedefcharLaufwerksname_t[2];
8
>Laufwerksname_tListeLaufwerke[NB_LAUFWERKE_MAX];
9
>
10
>voidprint(Laufwerksname_tconst*constListe)//WARNUNG FÜR DIESE
warning: passing arg 1 of `print' from incompatible pointer
2
> type
.
> Wenn ich den ersten const (oben markiert) entfernt passt alles.> Warum? Das Argument Liste ist ein Array bzw. ein konstanter Pointer auf> einige Einträge. Jeder dieser Einträge ist ein String, also ein> Char-Array und somit ein weiterer Pointer. Der Inhalt vom Char-Array ist> nicht konstant, der Pointer auf das Array schon, also 2 mal const. Wo> ist mein Denkfehler?
Schlauch schrieb:> Ich kann den Code oben auch mit -Wall ohne Warnungen oder Fehler> kompilieren (gcc 4.3.3).
Du meinst Problem 1 (const * const Liste)?