optionaler Parameter
-
Da ich bei D3D-Anwendungen immer wieder Ärger mit dem Debuggen hatte, habe ich mir irgendwann mal eine kleine Funktion geschrieben, die die Fehlerausgabe vereinfachen sollte. Soweit ich mich erinnerte, lief sie bisher auch reibungslos.
Jetzt habe ich allerdings von VS 6.0 auf VS .Net 2003 gewechselt.
bool Log(LPSTR msg,...){ // Variablen int flag; va_list pz; // Argumentzeiger va_start(pz, msg); // Argumentzeiger wird auf ersten optionalen Parameter gesetzt flag = va_arg(pz, int); if(!flag) // falls kein optionaler Parameter eigetragen wurde flag = 1; va_end(pz); // Argumentzeiger resetten [...]
Wenn ich mich richtig erinnere, bekam mit VS 6.0 flag die 0 zugewiesen, wenn kein optionaler Parameter nach LPSTR msg übergeben wurde.
Bei VS.Net 2003 hingegen bekomme ich jetzt irgendwelche komischen Werte...In der MSDN und auch hier im Forum konnte ich keinen Hinweis finden, welchen Wert va_arg zurückliefert, wenn va_arg aufgerufen wird, auch wenn die Parameterliste zu Ende ist.
Im Moment habe ich es gelöst, indem ich die if-Abfrage geändert habe:
if(flag < 1 || flag > 3)
Mit dem Workaround gibt es aber spätestens dann Probleme, wenn der "zufällige" Wert, den flag bekommt, mal gerade 1-3 ist.
Weiss jemand, wo der Fehler steckt?
-
Schau mal in die MSDN
-
Da komm ich her.
Hast du vielleicht nen Hinweis, auf welcher Seite in der MSDN ich weiterkomme? Link wäre super.
-
wvsprintf
-
Da komm ich her.
Also hast Du nicht verstanden, was da steht
va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list
Bedeutet, dass flag abhängig davon ist, welcher Parameter gerade gelesen wird. Da Du unterschiedliche Parameter hast, muss logischerweise auch flag immer unterschiedlich sein. Und das ist schon länger so, nicht erst seit .NET !
There is no mechanism for testing whether there is actually a next argument available; you might instead pass an argument count (or some other data that implies an argument count) as one of the fixed arguments in your function call.
D.h. Es gibt keinen gültigen Ende-Zeiger! Entweder musst du die Anzahl als Parameter oder einen gültigen Ende-Wert mit übergeben.
-
@luke
für was brauchst du die anzahl der parameter ?mach es doch so
void Log(char *msg,...) { FILE* file; char buffer[256]; file = fopen("log.txt", "a+"); va_list msglist; va_start(msglist, msg); vsprintf(buffer, msg, msglist); va_end(msglist); fprintf(file, "%s", buffer); fclose(file); }
-
@René: Habe es vielleicht nicht klar genug geschrieben, oder verstehe den ersten Punkt bei dir nicht.
Der Funktionsaufruf sieht folgendermaßen aus:
Log(STRING,[flag]);
Flag ist dabei IMMER vom Datentyp int (Wert zwischen 1 und 3); mehr Parameter gibt es nicht. Es wäre also auch durch Funktionsüberladung möglich, will ich aber nur im Notfall machen, da die Funktion auch in einigen älteren C-Programmen verwendet wird.Wird flag nicht angegeben, soll die Funktion so arbeiten, als wäre 1 übergeben worden.
Dein 2. Zitat habe ich wohl in der MSDN übersehen...
@miller_m: Ich brauche nicht die Anzahl der Parameter... ich muss nur wissen ob überhaupt der "flag"-Parameter übergeben wurde, oder ob der nicht gesetzt war. Wenn er nicht gesetzt ist/übergeben wurde, soll die Funktion arbeiten (default) als wäre eine 1 übergeben worden... Wobei ich mir langsam nicht mehr sicher bin, ob das überhaupt mit optionalen Parametern möglich ist, oder ob kein Weg an Funktionsüberladung dran vorbei führt.
@<redu>&miller_m:
Danke für den Tipp mit vsprintf. So eine Funktion hab ich schon seit Monaten gesucht. Behebt zwar nicht das eigentliche Problem, aber damit kann ich dann die Log-Funktion ausbauen und muss nicht immer vor dem Aufruf sprintf benutzen, wenn ich Text formatieren will.Der komplette Quellcode ist unter http://www.luke1410.de/xfighter.rar unter SourceCode\log.cpp zu finden, falls das vielleicht dann verständlicher ist.
[ Dieser Beitrag wurde am 12.05.2003 um 17:53 Uhr von Luke1410 editiert. ]