Last evening I spent hours debugging a problem that turned out to be a wrong type parameter passed to variadic function.
Last evening I spent hours debugging a problem that turned out to be a wrong type parameter passed to variadic function.
Last evening I spent hours debugging a problem that turned out to be a wrong type parameter passed to variadic function.
The way variadic arguments work is that the type of the variable determines how it is stored in the parameter array (the implementations between different platforms and ABIs differ here, there's no single solution). You then read the parameters in the actual function implementation with va_arg(va, type).
Where things fall apart is that there is no way to perform argument type checking (sure there is a attribute ((format)) which helps with certain specific function types that have format specifiers, but this is not a generic solution).
This gets messy when the type of the argument is isn't explicitly specified. Imagine this example:
#include <stdio.h>#include <stdarg.h>
void func(int foo, ...){ va_list va; va_start(va, foo); long long arg = va_arg(va, long long); printf("%lld\n", arg); va_end(va);}
int main(void){ func(1, 2);}
That gives no warnings at all. It also fails terribly on many platforms where 32-bit value is placed in argument and then 64-bits is read from it. Needless to say this is a recipe for hard to find bugs.
What you have to do here is to ensure that the caller is explicit about the types of the arguments. So, for example the following work correctly:
func(1, 2LL); func(1, (long long) 2); long long a = 2; func(1, a);
#programming #C