selective linking of floating point support for *printf / *scanf

Thomas Preud'homme
Thu Aug 14 09:38:00 GMT 2014

> From: Joern Rennecke []
> Sent: Thursday, August 14, 2014 4:52 PM
> Newlib also has an integer-only printf implementation, but in this case,
> the default is the other way round - you have to use functions with
> nonstandard
> names to use the integer-only implementations.  And a half-hearted
> approach to
> use this can easily end up with linking in both the integer-only version and
> the
> floating-point enabled one, resulting in increased executable size instead of
> a saving.

A recent commit in newlib also added a configure option that split the float
support into weak functions such that they are not pulled by default. The
user then just need to define the symbol for the float support to be pulled
in. This allow the user to make the decision at link time rather than compile
> I think we can do better with integrated compiler/linker support.
> Trying to do a perfect job i of course impossible because of Rice's theorem,
> but it doesn't have to be perfect to be useful.
> Just looking statically at each *printf statement, we can look at the format
> strings and/or the passed arguments.
> Floating point arguments are easier to check for by the compiler than parsing
> the format string.  There is already code that parses the format strings for the
> purpose of warnings, but it would be a somewhat intrusive change to add
> this
> functionality there, and the information is not available where a variable
> format is used anyway.

We worked on some similar feature but looking at the format string as I
was not aware of the necessity that types of argument match the format
string. The result is not very intrusive. However indeed checking the
argument works in more cases as it would only fail when a va_list is passed.

> In a standards-conformant application, floating point formats can only be
> used
> with floating point arguments, so checking for the latter seems most
> effective.
> So my idea is to make the compile emit special calls when there are no
> floating
> point arguments.  A library that provides the floating point enabled
> *printf/*scanf
> precedes libc in link order.
> Libc contains the integer-only implementations of *scanf/*printf, in two
> parts:
> entry points with the special function name, which in the same object file
> also contain a reference to the ordinary function name, and another object
> file
> with the ordinary symbol and the integer-only implementation.
> Thus, if any application translation unit has pulled in a floating-point enabled
> implementation, this is the one that'll be used.  Otherwise, the integer-only
> one will be used.
> Use of special sections and alphasorting of these in the linker script
> ensures that the integer-only entry points appear in the right place at
> the start of the chosen implementation.
> If vfprintf is used

As said above, we had our own approach which we intended to post now that
float support in newlib can be put in weak function (the patch depends on this)
but since your patch does not require any change to newlib it might be
interesting to follow your approach instead.

> I've implemented this for AVR with these commits:
> gcc/commit/3b3bfe33fe29b6d29d8fb96e5d57ee025adf7af0
> libc/commit/c55eba74838635613c8b80d86a85ed605a79d337
> gdb/commit/72b3a1ea3659577198838a7149c6882a079da403
> Although it could use some more testing, and thought how to best
> introduce the change as to avoid getting broken toolchains when
> components
> are out-of-sync.

I'll give your patch a try and see if everything works fine.

> Now Joerg Wunsch suggested we might want to facto out more pieces, like
> the
> long long support.  This quickly leads to a combinatorial explosion.
> If we want to support a more modular *printf / *scanf, than maybe a
> different
> approach is warranted.
> Say, if we could give a symbol and section attribute and/or pragma to
> individual
> case labels of a switch, and put the different pieces into separate object
> files (maybe with a bit of objcopy massaging).
> The symbols references to trigger the inclusion of the case objects could be
> generated by the gcc backend by processing suitably annotated function calls.
> E.g. we might put something into CALL_FUNCTION_USAGE, or play with

Couldn't this be done as a second step? This is internal detail of GCC and thus
it should be fine to go forward with the current patch and change the
mechanic later.

Best regards,


More information about the Newlib mailing list