2012-08-27 10 views
6

Mój kod zawiera fragmenty, takie jak:SBRM/RAII dla std :: va_list/va_start()/va_end używać

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

Są krótkie i va_start() i va_end() są blisko siebie, więc nie są one wielkim problemem . Wyjątki od połączeń pomiędzy nimi mogą być problemem (lub nie?).

Prosty test pokazuje, że wywoływanie va_start() z funkcji bez wielokropka jest niedozwolone. Czy wywołanie va_end() z innej funkcji niż va_start() zostało wywołane z dozwolonej, czy nie?

Zasadniczo, jestem ciekawy, czy możliwe jest, aby użyć idiomu SBRM/RAII dla tych połączeń, nawet jeśli to było konieczne, aby zadzwonić va_start() ręcznie, a następnie przekazać instancję std::va_list do mojego RAII/SBRM przykład straży?

Odpowiedz

6

Niestety, nie. Specyfikacja va_start i va_end wymaga:

każdego wywołania z va_start i va_copy makr powinna być dopasowana przez odpowiednie wezwaniem va_end makro w tym samym funkcji.

Dlatego va_end musi być w samej funkcji variadic, a nie destruktorze klas.

+0

Gdzie jest cytat? – wilx

+0

@wilx: Standard C99, 7.15.1/1. –

0

Jedna z możliwych implementacji zakłada std :: va_list = char *, a va_end() ustawia wskaźnik na wartość null. Przyczyna może być nazywana poza funkcją. Ale nie jestem pewien, że będzie działać podobnie na innych platformach.

Lepiej zapakować te funkcje w klasę.

Powiązane problemy