warning: passing argument 1 of 'putString' discards qualifiers from pointer target type danke mgiaco
Wie ist putString definiert und was wird übergeben? So kann man Dir leider nicht helfen.
Warnung: Die Übergabe von Argument 1 von "putString" verwirft Qualifizierer des Zeiger-Ziel-Typs... Jetzt klar? Auch wenn es mit Sicherheit sinnvoll gewesen wäre, den zu der Meldung gehörenden Code zu posten: Solche Warnungen gibts, wenn man einer Funktion, die einen Datentypen ohne Typqualifizierer erwartet, eine Variable übergibt, die z.B. volatile oder static ist. I.d.R. kann man diese Warnungen ignorieren.
Ja sorry vergessen stimmt.
1 | void putString(char *str) { |
2 | |
3 | char *temp = str; |
4 | uint8_t x = getX(); //get actual X |
5 | uint8_t y = getY(); //get actual Y |
6 | uint8_t xtemp, ytemp; |
7 | |
8 | xtemp = x; |
9 | ytemp = y; |
10 | |
11 | calcXY(temp,&xtemp,&ytemp); |
12 | |
13 | gotoXY(xtemp,ytemp); |
14 | |
15 | while(*temp != 0) { |
16 | if(*str == '\n') { |
17 | gotoXY(x, getY()+FontRead(myDC->FontSettings.Font+FONT_HEIGHT)); |
18 | } else { |
19 | putChar(*temp); |
20 | }
|
21 | temp++; |
22 | }
|
23 | |
24 | gotoXY(x,y); //restore x, y position |
25 | }
|
Aufruf: putString(Item->text); Item struct
1 | typedef struct menueItem{ |
2 | |
3 | struct menueIcon *menueIcon; //Icon zum Beispiel Batterie-Symbol |
4 | const char *text; |
5 | char *value; |
6 | u8_t flags; |
7 | struct menueItem *next; |
8 | struct menueItem *prev; |
9 | struct menueItem *parent; |
10 | struct menueItem *child; |
11 | |
12 | }MenueItem; |
ja ich weis es ist eine const char denn ich übergebe ich mach mir aber eine kopie in putstring. danke
>ja ich weis es ist eine const char denn ich übergebe ich mach mir aber >eine kopie in putstring. Genau das ist das Problem. Das const wird verworfen. Wenn Du
1 | void putString( const char *str ) |
definierst, dürfte die Warnung weg sein.
und "const" ist der Qualifier, den du verwirfst. Lösung: Statt putString(char ...) einfach putString(const char ...)
Jo okay habe ich auch gemacht, aber dann kommt halt die warning wenn ich kein const char übergebe. Möchte man vielleicht auch mal.
mgiaco wrote: > Jo okay habe ich auch gemacht, aber dann kommt halt die warning > wenn ich kein const char übergebe. Das glaub ich nicht, Tim. Einen char* an eine Funktion zu übergeben, die einen const char* erwartet ist absolut ungefährlich. Da kann nichts passieren, solange der Programmierer in der Funktion das const nicht wegcastet. Einen const char* an eine Funktion zu übergeben, die einen char* erwartet ist hingegen gefährlich.
was meinst du mit wegcasten. Ich weis was casten heißt aber wie ist das mit wegcasten gemeint.
1 | void foo( const char * data ) |
2 | {
|
3 | // normalerweise geht das nicht ...
|
4 | |
5 | data[0] = 'a'; |
6 | |
7 | // ... weil ja data ein Pointer ist, der auf Character
|
8 | // zeigt und diese Character sind konstant, also
|
9 | // nicht veränderbar.
|
10 | |
11 | // aber ich kann den const ja auch wegcasten
|
12 | |
13 | char* nonConstData = data; |
14 | |
15 | // und dann kann ich sehr wohl versuchen die Character
|
16 | // zu verändern ...
|
17 | |
18 | nonConstData[0] = 'a'; |
19 | |
20 | // ... kein Compiler wird sich daran stossen.
|
21 | }
|
und dann habe ich die paradoxe Situation, dass zwar der Funktionskopf void foo( const char* data ) mir als Aufrufer die Zusicherung gibt, dass sich die Funktion foo nicht am übergebenen String vergreifen wird, ich also bedenkenlos auch einen konstanten String hineingeben darf ...
1 | int main() |
2 | {
|
3 | foo( "xyz" ); |
4 | }
|
... sich die Funktion selbst sich aber nicht an diese Zusicherung hält und genau dies versucht. Ich denke es ist nicht notwendig zu erwähnen, dass die Verwendung eines cast um einen const los zu werden, sofort undefiniertes Verhalten des Programmes nach sich zieht.
Ja okay, aber wie macht mans denn richtig? Prozessor ist eine ARM7 und ich möchte das die Strings im Flash stehen deshalb const. mgiaco
Die Sache ist ganz einfach: Verändert die Funktion den übergebenen String oder verändert die ihn nicht? Wenn die Funktion den übergebenen String nicht verändert, dann machst du den Funktionskopf
1 | void foo( const char* String ) |
2 | {
|
3 | // mach was mit String, wobei der String selbst nicht
|
4 | // verändert wird.
|
5 | // Falls du versuchst den String zu verändern, klopft dir
|
6 | // der Compiler auf die Finger
|
7 | }
|
Dadurch, dass das Argument ein const char* ist, kannst du das dann auch mit einem konstanten String aufrufen
1 | int main() |
2 | {
|
3 | char test[] = "Hallo world"; |
4 | |
5 | foo( test ); // kein Problem |
6 | foo( "Hallo world" ); // auch kein Problem |
7 | }
|
Verändert aber die Funktion den übergebenen String, dann dokumentierst du das auch im Funktionskopf:
1 | void foo2( char* String ) |
2 | {
|
3 | // mach was mit dem String
|
4 | // das kann auch soweit gehen, dass der String verändert wird
|
5 | }
|
Und dadurch dass das Argument jetzt nur noch ein char* ist, kannst du logischerweise keinen konstanten String im Aufruf benutzen. Denn die Funktion wird ja den String verändern, was bei einem konstanten String nicht gehen wird.
1 | int main() |
2 | {
|
3 | char test[] = "Hallo world"; |
4 | |
5 | foo2( test ); // kein Problem |
6 | foo2( "Hallo world" ); // hier wird der Compiler meckern. foo |
7 | // würde versuchen, den String zu verändern.
|
8 | // Das ist bei einem Stringliteral aber nicht
|
9 | // erlaubt.
|
10 | }
|
Wie geasagt: Die Sache ist ganz einfach. Du musst dir nur darüber im Klaren sein, welche Aussage 'const' in einem C-Programm macht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.