2012-08-27 4 views
6

Meine Code-Schnipsel wie diese enthält:SBRM/RAII für std :: va_list/va_start()/va_end verwenden

std::va_list ap; 
    va_start(ap, msgfmt); 
    snprintf_buf buf; 
    const tchar * msg = buf.print_va_list(msgfmt, ap); 
    va_end(ap); 

Diese sind kurz und va_start() und va_end() nahe beieinander liegen, so dass sie nicht viel von einem Problem sind . Ausnahmen von Anrufen zwischen den beiden könnten ein Problem sein (oder nicht?).

Einfacher Test zeigt, dass va_start() aus einer Funktion ohne Auslassungs Aufruf ist nicht erlaubt. Ruft va_end() von einer anderen Funktion als va_start() wurde von erlaubt oder nicht?

Grundsätzlich bin ich gespannt, ob es möglich ist, die SBRM/RAII Idiom für diese Anrufe zu verwenden, auch wenn es notwendig wäre va_start() manuell aufrufen und dann Instanz std::va_list in Beispiel meine RAH/SBRM Wache passieren?

Antwort

6

Leider nicht. Die Spezifikation der va_start und va_end erfordert, dass:

jeden Aufruf des va_start und va_copy Makros wird von einem entsprechenden Aufruf des Makros va_endin der gleichen Funktion angepasst werden.

Daher muss va_end in der Variadic-Funktion selbst sein, nicht ein Klassenzerstörer.

+0

Wo ist das Zitat aus? – wilx

+0

@wilx: Der C99 Standard, 7.15.1/1. –

0

Eine mögliche Implementierungen geht davon aus std :: va_list = char * und va_end() setzt nur, dass Zeiger auf null. Natürlich kann es außerhalb der Funktion aufgerufen werden. Aber ich bin nicht sicher, dass es auf anderen Plattformen ähnlich funktioniert.

besser, diese Funktionen mit einer Klasse zu wickeln.

Verwandte Themen