2010-12-29 10 views
2

Alle,C++ va_arg typecast ausgabe

Ich schreibe eine kleine C++ App und bin durch dieses Problem ratlos geworden. Gibt es eine Möglichkeit, den Fehler beim Zugriff auf das Element aus dem va_list-Makro mithilfe von va_arg zu erstellen (und später zu fangen), wenn der Elementtyp nicht erwartet wird. ZB: -

count=va_arg(argp,int); 
if (count <= 0 || count > 30) 
{ 
     reportParamError(); return; 
} 

Nun, wenn ich einen typedef statt int bin vorbei, erhalte ich Müll Wert auf MS-Compiler, aber 95% der Zählzeit wird Wert 0 auf gcc (auf 64-Bit SLES10 sys). Gibt es eine Möglichkeit, eine Art der Überprüfung zu erzwingen, so dass ich einen Fehler bekomme, der in einem Catch-Block gefangen werden kann?

Alle Ideen dazu wären sehr hilfreich für mich. Oder gibt es einen besseren Weg, dies zu tun? Der Funktionsprototyp ist: -

void process(App_Context * pActx, ...) 

Die Funktion als

process(pAtctx,3,type1,type2,type3); 

genannt wird Es ist wichtig, für pActx als erster Parameter übergeben werden und somit nicht als 1. Parameter zählen passieren kann.


-Update-1

Ok, das klingt seltsam, aber nargs scheint nicht von va_list auf SLES10 gcc zu Teil. Ich musste setzen

#ifdef _WIN32 
tempCount=va_arg(argp,int) 
#endif 

Nach der Verwendung, Parameter folgen Narg nicht Müll Werte. Dies führt jedoch Compiler/Plattform basierte #ifdefs .... Danke Chris und Kristopher

+1

Warum nicht die Zählung zum 2. Parameter machen? 'void process (App_Context * pActx, std :: size_t nargs, ...);' –

+0

@Chris, danke für deinen Vorschlag. Ich war mit dieser Option gegangen, aber mit Gcc, der 1. Parameter (Typ 1) nach NARGS bekommt Müll Wert. Der letzte Parameter erhält auch einen ungültigen Wert.Ich nehme an, dass nargs auch Teil von va_list im Sinne von va_start (argp, App_Context *) gefolgt von va_arg (argp, int) ist. – confused

Antwort

2

Nein, es gibt keine Möglichkeit. varargs bietet keine Möglichkeit, die übergebenen Typen von Parametern zu überprüfen. Sie müssen sie nur mit dem richtigen Typ lesen, was bedeutet, dass Sie eine andere Art der Kommunikation von Typinformationen benötigen.

Sie sind wahrscheinlich besser dran, wenn Sie die Funktionalität von varargs vermeiden, es sei denn, Sie benötigen sie wirklich. Es ist nur eine C++ - Funktion für Legacy-Funktionen wie printf und Freunde.

+0

Danke für eine schnelle Antwort. – confused

+0

+1 das grundlegende Problem hier ist, dass "Haupt" Typ-unsicher ist, wie durch den Standard definiert. –

5

Wenn Sie eine Zählung wissen immer als zweites Argument übergeben wird, dann immer man konnte die Signatur dies ändern:

void process(App_Context * pActx, int count, ...) 

Wenn das keine Option ist, dann gibt es wirklich keine Möglichkeit, es zu fangen . So funktioniert die Variable argument-list: Der Angerufene kann nicht wissen, welche Argumente übergeben werden, abgesehen von den Informationen, die der Anrufer weitergibt.

Wenn Sie untersuchen, wie die Makros va_arg und zugehörige Makros implementiert sind, können Sie möglicherweise herausfinden, wie Sie alle Daten auf dem Stapel überprüfen können. Dies wäre jedoch nicht tragbar und wird nur als Debug-Hilfe empfohlen.

Sie könnten auch Alternativen zu Variablenargumenten untersuchen, wie Überladen von Funktionen, Vorlagen oder die Übergabe eines vector oder list Arguments.

+0

vielen Dank für Ihren Vorschlag. Ich hatte den von dir erwähnten Ansatz ausprobiert. Ich hatte ein Problem mit diesem Ansatz. Das erste Argument nach der Zählung hat immer einen Müllwert auf dem 64-Bit-System von sles10 erhalten. Die va_list stammt aus einer .c-Datei. Nach einigen grundlegenden Überprüfungen wird die va_list an eine CPP-Datei übergeben. Dort kommt das Müllproblem ins Bild. In der .c-Funktion habe ich va_start (argp, App_Context *). count = va_arg (argp, int). Dann rufe ich den Prozess (pActx, count, argp) auf. Darin ist va_arg (argp, type1). Da Typ1 immer einen Müllwert hatte, musste ich den Ansatz ändern. – confused