Warnung bei char in va_arg

Hallo
Ich habe ein Problem mit folgendem Code, denn mein Compiler(GCC/Xcode) gibt mir die Warnung „char' is promoted to int’ when passed through `…’“ aus. Hier der Code:

Search\_Result \* search(short length\_of\_arg\_string,char \* arg\_string,...){
 ...
 char \* datastring;
 short i=0;
 va\_list additional\_arguments;
 va\_start(additional\_arguments,length\_of\_arg\_string);
 datastring=va\_arg(additional\_arguments,char\*);
 ...
 cdata=va\_arg(additional\_arguments,char);//
Schon mal Danke an alle, die mir helfen können,
Stefan

Warnung auch bei short
Hallo
Das Problem habe ich auch, wenn ich statt char short verwende. Dann heißt die Warnung „short int' is promoted to int’ when passed through `…’“

Das Problem :

char ist 1 Byte und default und es gibt signed und unsigned char
int ist mehrere bytes gross.

Da du char nicht explizit unsigned oder signed gemacht hast
weiss der compiler nicht obs nun (minus oder pluss ist)
Also gibts auch mehrere möglichkeiten für den INT wert

value could become either 0xff 0xff or 0x00 0xff

Der rest ergibt sich aus den Problem :smile:

also unsigned char !!!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo
Das Problem habe ich auch, wenn ich statt char short verwende.
Dann heißt die Warnung „short int' is promoted to int’ when
passed through `…’“

Selbiges problem , (signed oder unsigned nicht angegeben) ergeben mehrdeutige INT (signed unsigned). :smile:

Hallo,

Ich habe ein Problem mit folgendem Code, denn mein
Compiler(GCC/Xcode) gibt mir die Warnung „char' is promoted to int’ when passed through `…’“ aus. Hier der Code:

Der Grund dafür ist, dass C/C++ nur
„Maschinenworte“ auf dem Stack ablegen
kann, weil es eben den direkten
„Maschinenstack“ benutzt.

Die Warnung bedeutet:

  • der char wird in Maschinenwort umgewandelt
  • das Maschinenwort wird auf den Stack gelegt

Siehe auch:
http://www.unixpapa.com/incnote/variadic.html

 The type given as the second argument of the 
 va\_arg() macro should generally not be char, 
 short or float. That's because if these types 
 are passed to the function, they will be promoted 
 to int or double before they are passed in. 
 There can be portability problems if you give 
 the original types instead of the promoted types.

In den meisten Fällen wird es aber dennoch o.k.
funktionieren.

Grüße

CMБ

Hallo,

Ich habe ein Problem mit folgendem Code, denn mein
Compiler(GCC/Xcode) gibt mir die Warnung „char' is promoted to int’ when passed through `…’“ aus. Hier der Code:

Der Grund dafür ist, dass C/C++ nur
„Maschinenworte“ auf dem Stack ablegen
kann, weil es eben den direkten
„Maschinenstack“ benutzt.

Die Warnung bedeutet:

  • der char wird in Maschinenwort umgewandelt
  • das Maschinenwort wird auf den Stack gelegt

Aha, und wenn ich dich richtig interpretiere
würde auch ein
unsigned char, bzw signed char explizit angegeben,
oder Compiler /J flag , auch deine Warnung ergeben.
Tut sie aber nicht, da mit /J
ausdrücklich gesagt wird das
CHAR -> unsigned INT festgelegt wird.
Und da wird auch das char in das Maschinenwort wird auf den Stack gelegt.

Problem erkannt , problem gebannt :-!

Hallo RakonDark

Aha, und wenn ich dich richtig interpretiere
würde auch ein
unsigned char, bzw signed char explizit angegeben,
oder Compiler /J flag , auch deine Warnung ergeben.
Tut sie aber nicht, da mit /J
ausdrücklich gesagt wird das
CHAR -> unsigned INT festgelegt wird.
Und da wird auch das char in das Maschinenwort wird auf den
Stack gelegt.

Problem erkannt , problem gebannt :-!

Danke für die Hilfe, aber könntest du vielleicht ein Codebeisspiel dafür geben? So ganz hab ich das noch nicht verstanden.
Stefan

Ja ist aber auf english , verdeutlicht das problem
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?ans…
und einmal in der MSDN

Fundamental Types
http://msdn2.microsoft.com/en-us/library/cc953fe1.aspx

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

1 Like

Bei va_start() muss der _letzte_ Parameter angegeben werden.
In deinem Beispiel also

va\_start(additional\_arguments, arg\_string);

va_arg() nimmt nunmal keine chars oder shorts, etc. Den Grund hat Semjon in seinem Post schon genannt. An einem Beispiel verdeutlicht:

void func(char c);

. Wenn du dieser Funktion die Zahl 5 übergibts, dann wird der Wert intern in nem int abgespeichert, und in der Funktion automatisch wieder nach char zurückverwandelt, ohne dass Du dich darum kümmern musst.

Wenn du aber „variadic functions“ (das sind die drei Punkte) benutzt, musst man sich um die Umwandlung der typen selbst kuemmern. Also folgendes Beispiel ist macht evtl. ein wenig deutlich was passiert:

#include 
#include 
 
void variadic\_function(const char\* text, ...) 
{ 
 va\_list ap; 
 char var; 
 int intvar; 
 
 // dies funktion erwartet einen char. 
 va\_start(ap, text); 
 var = (char)va\_arg(ap, int); 
 va\_end(ap); 
 
 // testhalber nochmal holen, diesmal aber als int 
 va\_start(ap, text); 
 intvar = va\_arg(ap, int); 
 va\_end(ap); 
 
 printf("%-20s: %d (int wuerde sein: %d)\n", text, var, intvar); 
} 
 
int main(void) 
{ 
 // die funktion erwartet einen char
 variadic\_function("pass (char)5", (char)5); 
 
 // folgendes schadet aber auch nicht, weil ja sowieso
 // platz fuer einen ganzen int ist, und nicht nur fuer char.
 variadic\_function("pass 5", 5); 
 variadic\_function("pass (short)5", (short)5); 
 variadic\_function("pass (int)5", (int)5); 
 
 // wenn es aber ueber -128..127 hinausgeht, gibts probleme 
 // weil die funktion nur char erwartet und den Wert
 // auch entsprechend interpretiert.
 variadic\_function("pass 200", 200); 
 
 // davor schuetzt man sich am besten, indem man
 // den expliziten cast hinschreibt, auch wenn er an sich
 // nicht noetig waere.
 // (hier sieht man sofort: (char)200 geht bestimmt schief)
 variadic\_function("pass (char)200", (char)200); 

 return 0; 
} 

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Bei va_start() muss der _letzte_ Parameter angegeben werden.
In deinem Beispiel also

va_start(additional_arguments,
arg_string);

Ja, da hast du recht. Die Funktion ist aber etwas komplizierter als gepostet. Es können Parameter vor arg_string benötigt werden, deshalb wird auch der mit va_arg eingelesen. Für das Forum hab ichs vereinfacht, va_start aber vergessen