Home > Software design >  Why does 'printf("%Lf", 1.0);' results in a segfault in C?
Why does 'printf("%Lf", 1.0);' results in a segfault in C?

Time:10-13

Running with mingw compiler, this line:

printf("%Lf", 1.0);

results in a segfault. Why? I get it that '1.0' is double and not long double, as '%Lf' specifies, but I'd expect a conversion of some sort, not a segfault.

CodePudding user response:

There is no implicit conversion for double in variadic function call, from documentation no mention of conversion from double:

In a function call expression when the call is made to ... a variadic function, where the argument expression is one of the trailing arguments that are matched against the ellipsis parameter. Each argument of integer type undergoes integer promotion, and each argument of type float is implicitly converted to the type double

Access to individual variadic parameters is implemented via va_arg macro. From it's documentation there is undefined behavior if expected type is different than the passed type:

T va_arg( va_list ap, T );

...

If the type of the next argument in ap (after promotions) is not compatible with T, the behavior is undefined,

%Lf format indicates that printf expects and will try to read a long double value, (documentation: fprintf format). long double is mostly a 16-byte double, from cppreference.com :

long double - extended precision floating point type. Matches IEEE-754 binary128 format if supported

1.0 constant is double (almost always 8 bytes), from documentation:

An unsuffixed floating constant has type double

So long double type is expected, but double is passed, which is undefined behavior. Or 16 bytes parameter is expected, but 8 bytes passed, thus a segfault on an attempt to read uninitialized memory.

CodePudding user response:

Please read up on varargs. The only information that printf has about the type of the value is the format spec. You have asked printf to fetch a big item, and supplied a small item. This could cause a misaligned fetch or, remotely, even, an access beyond the bounds of the stack.

  •  Tags:  
  • c
  • Related