Description of problem: vsnprintf(buffer,size,"%s","crash"); will cause a crash. Version-Release number of selected component (if applicable): glibc-2.3.3-27.1 How reproducible: Always. Steps to Reproduce: 1. 2. 3. Actual results: Expected results: Additional info:
Hmm, that's to be expected. "crash" is not of type va_list. Either you call snprintf(buffer, size, "%s", "crash"); or vsnprintf(buffer, size, "%s", ap); where ap has va_list type and has been initialized by va_list or va_copy macros.
Sorry, in all haste yesterday evening after a long day tracing down the bug, I enterned the wrong example. Try this code and you will see that it crashes on the call with one arg: #include <stdio.h> #include <stdarg.h> static void p(char* line,size_t n,const char* format,va_list args) { vsnprintf(line,n,format,args); printf("%s\n",line); } static void p(char* line,size_t n,const char* format,...) { va_list args; va_start(args,format); p(line,n,format,args); va_end(args); } int main() { char line[128]; snprintf(line,128,"Santa %s","Monica"); printf("%s\n",line); p(line,128,"%s %li","California",90404); p(line,128,"USA"); p(line,128,"%s","North America"); return 0; }
That's still a bug in your testcase. The standard doesn't say what type is va_list and on some arches GCC (as well as other compilers) uses char *. This is the case of e.g. i386. But because you have p overloaded, then for p(line,128,"%s","North America"); p(char*, unsigned int, char const*, char*) is chosen (which is the one with va_list), while for the other calls p(char*, unsigned int, char const*, ...).
Looks like the standard has a limitation in not defining `va_list' as a unique type. `va_list' and `char*' have different semantics, so why not acknowledge that?
ISO C99 just requires va_list to be an object type suitable for holding information needed by va_{start,end,copy,arg}. ISO C++98 just requires va_list to be a type in <cstdarg> and the same as in ISO C90 applies there. Note that this can't be changed for binary compatibility reasons.