Forum: Compiler & IDEs Verstehe diese Fehlermeldung nicht


von mgiaco (Gast)


Lesenswert?

warning: passing argument 1 of 'putString' discards qualifiers from 
pointer target type

danke mgiaco

von Florian D. (code-wiz)


Lesenswert?

Wie ist putString definiert und was wird übergeben? So kann man Dir 
leider nicht helfen.

von Johannes M. (johnny-m)


Lesenswert?

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.

von mgiaco (Gast)


Lesenswert?

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

von Florian D. (code-wiz)


Lesenswert?

>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.

von Simon K. (simon) Benutzerseite


Lesenswert?

und "const" ist der Qualifier, den du verwirfst.

Lösung: Statt putString(char ...) einfach putString(const char ...)

von mgiaco (Gast)


Lesenswert?

Jo okay habe ich auch gemacht, aber dann kommt halt die warning wenn ich 
kein const char übergebe. Möchte man vielleicht auch mal.

von Karl H. (kbuchegg)


Lesenswert?

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.


von mgiaco (Gast)


Lesenswert?

was meinst du mit wegcasten. Ich weis was casten heißt aber wie ist das 
mit wegcasten gemeint.

von Karl H. (kbuchegg)


Lesenswert?

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.

von mgiaco (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von mgiaco (Gast)


Lesenswert?

Okay, super danke kapiert.

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.