mikrocontroller.net

Forum: Compiler & IDEs Verstehe diese Fehlermeldung nicht


Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warning: passing argument 1 of 'putString' discards qualifiers from 
pointer target type

danke mgiaco

Autor: Florian Demski (code-wiz)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja sorry vergessen stimmt.

void putString(char *str) {
  
    char *temp = str;
    uint8_t x = getX(); //get actual X
    uint8_t y = getY(); //get actual Y
    uint8_t xtemp, ytemp;
    
    xtemp = x;
    ytemp = y;
    
    calcXY(temp,&xtemp,&ytemp);
    
    gotoXY(xtemp,ytemp);
    
  while(*temp != 0) {
    if(*str == '\n') {
      gotoXY(x, getY()+FontRead(myDC->FontSettings.Font+FONT_HEIGHT));
    } else {
      putChar(*temp);
    }
    temp++;
  }
    
    gotoXY(x,y); //restore x, y position  
}


Aufruf: putString(Item->text);

Item struct
typedef struct menueItem{

    struct menueIcon *menueIcon; //Icon zum Beispiel Batterie-Symbol
    const char *text;
    char *value; 
    u8_t flags;
    struct menueItem *next;
    struct menueItem *prev;
    struct menueItem *parent;
    struct menueItem *child;

}MenueItem;

ja ich weis es ist eine const char denn ich übergebe ich mach mir aber 
eine kopie in putstring.

danke

Autor: Florian Demski (code-wiz)
Datum:

Bewertung
0 lesenswert
nicht 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
void putString( const char *str )

definierst, dürfte die Warnung weg sein.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und "const" ist der Qualifier, den du verwirfst.

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

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: mgiaco (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void foo( const char * data )
{
  // normalerweise geht das nicht ...

  data[0] = 'a';

  // ... weil ja data ein Pointer ist, der auf Character
  // zeigt und diese Character sind konstant, also
  // nicht veränderbar.

  // aber ich kann den const ja auch wegcasten

  char* nonConstData = data;

  // und dann kann ich sehr wohl versuchen die Character
  // zu verändern ...

  nonConstData[0] = 'a';

  // ... kein Compiler wird sich daran stossen.
}

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 ...
  int main()
  {
    foo( "xyz" );
  }

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

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
void foo( const char* String )
{
  // mach was mit String, wobei der String selbst nicht
  // verändert wird.
  // Falls du versuchst den String zu verändern, klopft dir
  // der Compiler auf die Finger
}

Dadurch, dass das Argument ein const char* ist, kannst du das
dann auch mit einem konstanten String aufrufen
int main()
{
  char test[] = "Hallo world";

  foo( test );            // kein Problem
  foo( "Hallo world" );   // auch kein Problem
}

Verändert aber die Funktion den übergebenen String, dann dokumentierst
du das auch im Funktionskopf:
void foo2( char* String )
{
  // mach was mit dem String
  // das kann auch soweit gehen, dass der String verändert wird
}

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.
int main()
{
  char test[] = "Hallo world";

  foo2( test );            // kein Problem
  foo2( "Hallo world" );   // hier wird der Compiler meckern. foo
                           // würde versuchen, den String zu verändern.
                           // Das ist bei einem Stringliteral aber nicht
                           // erlaubt.
}


Wie geasagt: Die Sache ist ganz einfach. Du musst dir nur darüber
im Klaren sein, welche Aussage 'const' in einem C-Programm macht.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, super danke kapiert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.