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

Thomas Preud'homme
Wed Aug 27 10:41:00 GMT 2014

> From: Joern Rennecke []
> Sent: Wednesday, August 27, 2014 6:13 PM
> I don't see how it can be any other way.  We want to be able to compile
> translation units individually, and then let the linker sort out if we need the
> floating point enabled implementation(s), and skip the integer-only ones if
> so.

Consider the new scheme in newlib when printf calls another function for
handling floating point formats. This other function is weakly defined so
that it's not pulled by default and printf is effectively integer only. You just
need to link with an extra -u option to pull in the float support.

> Well, the part of processing libraries in order is pretty much
> universal, although
> there are options to change that behaviour.  I'd  say you really have
> to know what
> you are doing when using these options.
> Now, to make the __int_printf function entry line up with the printf
> implementation,
> I'm relying on GNU AS (gas) linker scripts.  That part is
> unfortunately not so portable,
> so this trick has to be restricted to targets/configurations that use gas,
> or another linker (if any) that allows to alphasort the relevant sections.

Yes, I don't see the order of libraries as a problem for portability. I was
concerned of the following possible algorithm:

__int_printf is processed first and is found in libc. The linker sees that
__int_printf needs printf and search for printf according to libraries order
and so will find it in the next section. This printf doesn't provide float
support. Then the linker proceeds to process the next undefined symbol in
the object file that is printf and use the one already found.

I concede that such an algorithm looks more convoluted as it implies
some form of recursion instead of just having a queue where you put
the undefined symbol. Indeed I missed the linker script which is the most
obvious problem.

> The general problem also includes trying to decide definitely if we
> need a/any floating
> point enabled implementation(s) in cases with calls of va_list taking
> functions,
> (which. while not always, but usually also take the format as a
> variable), and have
> no non-va_list calls to decide the matter in favour of needing floating point.
> The question if any floating-point indicating actual format string
> and/or(*) va_list
> arguments reach the v*printf / v*scanf calls is non-trivial and
> respects functions
> (in the computability theory sense),  hence, this is not computable
> according to Rice's theorem.
> (*) Any way you language lawyer it, you can only chip away at the set
> of programs
> you can compute the answer for, but can never do it for the whole set.

Ok. Of course detecting more cases where an integer version of IO functions
would be enough would be nice but I'm already satisfied with the current
scheme. I'm wondering what's happening for v*printf: are they only defined
in the libc_float?

Would you accept a patch that would turn this solution into something also
suitable for newlib? For instance we would need to also include v*printf
and v*scanf functions into builtin as well. A new switch would also be
needed so that compiling newlib doesn't define the _printf_float and
_scanf_float symbols because of calls to v*printf and v*scanf functions.
I need to check if these calls are made in the same file in which case
I could maybe just guard the function call rewriting by a test checking if the
caller is itself a builtin.

Best regards,


More information about the Newlib mailing list