mention disabling GCC built-ins for customization

Message ID 2f2f96d3-5487-f791-8554-310beae0721b@gmail.com
State New, archived
Headers

Commit Message

Martin Sebor June 13, 2018, 6:19 p.m. UTC
  The GCC sprintf optimization introduced in GCC 7 relies on
the conformance of the library implementation of formatted
I/O functions.  When a sprintf customization changes
the effects of the function in a way that's observable by
a strictly conforming program it might interfere with
the optimization.

Since this may not be obvious to users the attached patch
adds a couple of sentences to the manual to make it clear
that the sprintf built-in handling needs to be disabled
when customizing the function.

Martin
  

Comments

Florian Weimer June 13, 2018, 8:35 p.m. UTC | #1
* Martin Sebor:

>  @strong{Portability Note:} The ability to extend the syntax of
>  @code{printf} template strings is a GNU extension.  ISO standard C has
> -nothing similar.
> +nothing similar.  When using the GNU C compiler or any other compiler
> +that interprets calls to standard I/O functions according to the rules
> +of the language standard it is necessary to disable such handling by
> +the appropriate compiler option.  Otherwise the behavior of a program
> +that relies on the extension is undefined.

Aren't there ISO extensions to C which define additional format
specifiers which GCC knows nothing about?  So maybe it makes more
sense to say that if the application uses format specifiers not known
by GCC, behavior is undefined (unless the compiler option is used).
  
Martin Sebor June 13, 2018, 8:55 p.m. UTC | #2
On 06/13/2018 02:35 PM, Florian Weimer wrote:
> * Martin Sebor:
>
>>  @strong{Portability Note:} The ability to extend the syntax of
>>  @code{printf} template strings is a GNU extension.  ISO standard C has
>> -nothing similar.
>> +nothing similar.  When using the GNU C compiler or any other compiler
>> +that interprets calls to standard I/O functions according to the rules
>> +of the language standard it is necessary to disable such handling by
>> +the appropriate compiler option.  Otherwise the behavior of a program
>> +that relies on the extension is undefined.
>
> Aren't there ISO extensions to C which define additional format
> specifiers which GCC knows nothing about?  So maybe it makes more
> sense to say that if the application uses format specifiers not known
> by GCC, behavior is undefined (unless the compiler option is used).

The GCC optimization is disabled when the format string contains
invalid or unhandled specifiers/modifiers etc, so even those may
still be undefined in Glibc they aren't a problem for GCC.

What would cause a problem for the GCC optimization is a change
to the behavior of one of the standard conversions, like %i, or
%s.  One example would be changing the number of bytes output by
the conversion.  Another example of a future GCC optimization
that would lead to undefined behavior is a hook that modified
the string argument to %s (when GCC starts to assume that
the argument is not clobbered by a sprintf call).

Martin
  
Florian Weimer June 13, 2018, 9:01 p.m. UTC | #3
* Martin Sebor:

> On 06/13/2018 02:35 PM, Florian Weimer wrote:
>> * Martin Sebor:
>>
>>>  @strong{Portability Note:} The ability to extend the syntax of
>>>  @code{printf} template strings is a GNU extension.  ISO standard C has
>>> -nothing similar.
>>> +nothing similar.  When using the GNU C compiler or any other compiler
>>> +that interprets calls to standard I/O functions according to the rules
>>> +of the language standard it is necessary to disable such handling by
>>> +the appropriate compiler option.  Otherwise the behavior of a program
>>> +that relies on the extension is undefined.
>>
>> Aren't there ISO extensions to C which define additional format
>> specifiers which GCC knows nothing about?  So maybe it makes more
>> sense to say that if the application uses format specifiers not known
>> by GCC, behavior is undefined (unless the compiler option is used).
>
> The GCC optimization is disabled when the format string contains
> invalid or unhandled specifiers/modifiers etc, so even those may
> still be undefined in Glibc they aren't a problem for GCC.

Good.

> What would cause a problem for the GCC optimization is a change
> to the behavior of one of the standard conversions, like %i, or
> %s.  One example would be changing the number of bytes output by
> the conversion.  Another example of a future GCC optimization
> that would lead to undefined behavior is a hook that modified
> the string argument to %s (when GCC starts to assume that
> the argument is not clobbered by a sprintf call).

So it's not so much about extending the syntax, but altering the
behavior of existing syntax, right?
  
Martin Sebor June 13, 2018, 9:30 p.m. UTC | #4
On 06/13/2018 03:01 PM, Florian Weimer wrote:
> * Martin Sebor:
>
>> On 06/13/2018 02:35 PM, Florian Weimer wrote:
>>> * Martin Sebor:
>>>
>>>>  @strong{Portability Note:} The ability to extend the syntax of
>>>>  @code{printf} template strings is a GNU extension.  ISO standard C has
>>>> -nothing similar.
>>>> +nothing similar.  When using the GNU C compiler or any other compiler
>>>> +that interprets calls to standard I/O functions according to the rules
>>>> +of the language standard it is necessary to disable such handling by
>>>> +the appropriate compiler option.  Otherwise the behavior of a program
>>>> +that relies on the extension is undefined.
>>>
>>> Aren't there ISO extensions to C which define additional format
>>> specifiers which GCC knows nothing about?  So maybe it makes more
>>> sense to say that if the application uses format specifiers not known
>>> by GCC, behavior is undefined (unless the compiler option is used).
>>
>> The GCC optimization is disabled when the format string contains
>> invalid or unhandled specifiers/modifiers etc, so even those may
>> still be undefined in Glibc they aren't a problem for GCC.
>
> Good.
>
>> What would cause a problem for the GCC optimization is a change
>> to the behavior of one of the standard conversions, like %i, or
>> %s.  One example would be changing the number of bytes output by
>> the conversion.  Another example of a future GCC optimization
>> that would lead to undefined behavior is a hook that modified
>> the string argument to %s (when GCC starts to assume that
>> the argument is not clobbered by a sprintf call).
>
> So it's not so much about extending the syntax, but altering the
> behavior of existing syntax, right?

Yes, that's probably pretty close.

Just to be clear, it extends beyond changes to the printf behavior
of directives.  A %s hook, for example, cannot rely on being called
for every %s conversion, even if it doesn't change its behavior.
(Say if all it did was count its occurrences.)  This is because
GCC transforms printf("%s", s) to puts(s) and sprintf(d, "%s", s)
to stcrpy(d, s).

But adding a hook for a new/undefined conversion specification
that doesn't match an existing one in any way should not be
okay.

Martin
  
Andreas Schwab June 14, 2018, 7:25 a.m. UTC | #5
On Jun 13 2018, Martin Sebor <msebor@gmail.com> wrote:

> diff --git a/manual/stdio.texi b/manual/stdio.texi
> index 38be236..d945955 100644
> --- a/manual/stdio.texi
> +++ b/manual/stdio.texi
> @@ -2963,7 +2963,11 @@ The facilities of this section are declared in the header file
>  
>  @strong{Portability Note:} The ability to extend the syntax of
>  @code{printf} template strings is a GNU extension.  ISO standard C has
> -nothing similar.
> +nothing similar.  When using the GNU C compiler or any other compiler
> +that interprets calls to standard I/O functions according to the rules
> +of the language standard it is necessary to disable such handling by
> +the appropriate compiler option.  Otherwise the behavior of a program
> +that relies on the extension is undefined.

The manual already says that redefining existing conversions causes
problems:

    You can redefine the standard output conversions, but this is probably
    not a good idea because of the potential for confusion.  Library routines
    written by other people could break if you do this.

We should extend that with a stronger language, independent of any
compiler behaviour.

Andreas.
  

Patch

ChangeLog:
	* manual/stdio.texi (Customizing printf): Add a note to disable
	built-in handling.

diff --git a/manual/stdio.texi b/manual/stdio.texi
index 38be236..d945955 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -2963,7 +2963,11 @@  The facilities of this section are declared in the header file
 
 @strong{Portability Note:} The ability to extend the syntax of
 @code{printf} template strings is a GNU extension.  ISO standard C has
-nothing similar.
+nothing similar.  When using the GNU C compiler or any other compiler
+that interprets calls to standard I/O functions according to the rules
+of the language standard it is necessary to disable such handling by
+the appropriate compiler option.  Otherwise the behavior of a program
+that relies on the extension is undefined.
 
 @node Registering New Conversions
 @subsection Registering New Conversions