Phil Rosenberg Phil Rosenberg - 4 months ago 20
C Question

Is va_list incompatible between C and C++?

I'm using a library (GNU MicroHttpDaemon) which passes out error messages through a callback which takes a va_list. I pass in a function pointer and if an error occurs then my function is called with a va_list and some other parameters. My problem is that when I receive the va_list it is garbage and attempting to use it causes an exception to be thrown.
I am using Visual Studio 2015 on Windows 10. MicroHttpDaemon was built with the same compiler. My best guess for the cause is that MicroHttpDaemon is written in C, but I am using C++. Can anyone confirm that this is the issue? If it is then is there anything I can do to get the arguments into my C++ code?
My callback is below in case it's any use. Note that it is a static method, so should in general be fine to use as a C callback I think.

void HttpDaemon::parseMessageVa(void * arg, const char * fmt, va_list &ap)
{
HttpDaemon *daemon = static_cast<HttpDaemon*> (arg);
size_t n = vsnprintf(nullptr, 0, fmt, ap);
char *buffer = nullptr;
try
{
buffer = new char[n + 1];
vsprintf(buffer, fmt, ap);
try
{
daemon->m_lastMessage = std::string(buffer);
}
catch (...)
{
delete[] buffer;
throw;
}
}
catch (...)
{
//buffer allocation failed
daemon->m_lastMessage = "Memory allocation failure.";
}
if(buffer)
delete[] buffer;
}

Answer

va_list &ap -- a callback from C won't pass anything by reference. The function should take the list by value.