2012-08-27 29 views
6

Mi código contiene fragmentos como éstos:SBRM/RAII para std :: va_list/va_start()/va_end utilizar

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

Estos son cortos y va_start() y va_end() están muy cerca, así que no son un gran problema . Las excepciones de las llamadas entre los dos podrían ser un problema (¿o no?).

La prueba simple muestra que no se permite llamar va_start() desde una función sin puntos suspensivos. ¿Se ha llamado o no permitido llamar a va_end() desde una función diferente a va_start()?

Básicamente, estoy ansioso por ver si es posible utilizar el lenguaje SBRM/RAII para estas llamadas, incluso si fuera necesario llamar va_start() manualmente y después de pasar instancia de std::va_list en mi RAII/SBRM ejemplo guardia?

Respuesta

6

Lamentablemente, no. La especificación de va_start y va_end requiere que:

cada invocación de la va_start y va_copy macros se corresponde con una invocación correspondiente de la va_end macro en la misma función.

Por lo tanto, va_end debe estar en la función variadic en sí, no en un destructor de clase.

+0

¿De dónde es la cita? – wilx

+0

@wilx: El estándar C99, 7.15.1/1. –

0

Una de las posibles implementaciones asume que std :: va_list = char * y va_end() simplemente establece ese puntero a nulo. Por causa, se puede llamar fuera de la función. Pero no estoy seguro de que funcione de manera similar en otras plataformas.

Es mejor ajustar estas funciones con una clase.

Cuestiones relacionadas