Bug 15685 - printf("%s\n") optimized to puts also when parameter might be null
Summary: printf("%s\n") optimized to puts also when parameter might be null
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-05-27 17:05 UTC by Mikko Tiihonen
Modified: 2007-10-19 14:46 UTC (History)
3 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build: x86_64-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikko Tiihonen 2004-05-27 17:05:05 UTC
The glibc printf %s allows NULL as a parameter while puts() does't so gcc should
not convert the printf to puts unless it is certain that the parameter is not null.
On the other hand if the parameter is certainly null one could call puts("(null)");

See also: bug #15574
Example code:

% cat > bug.i << EOF
extern int printf (__const char *__restrict __format, ...);

int main ()
{
        printf ("%s\n", ((void *)0));
        return 0;
}
EOF
% gcc bug.i
% ./a.out
(null)
% gcc bug.i -O
% ./a.out
segmentation fault
Comment 1 Andrew Pinski 2004-05-27 17:10:13 UTC
Not a bug as printf can segfault if it is supplied a NULL pointer for the string formatter.
If glibc does something different than that, glibc is does not have a bug either as it is undefined really 
so converting the call to a puts is a vaild transformation.
Comment 2 Andrew Pinski 2005-12-30 23:07:11 UTC
*** Bug 25609 has been marked as a duplicate of this bug. ***
Comment 3 Andrew Pinski 2005-12-30 23:49:35 UTC
*** Bug 25609 has been marked as a duplicate of this bug. ***
Comment 4 mathias.hasselmann 2007-10-01 06:45:40 UTC
(In reply to comment #1)
> Not a bug as printf can segfault if it is supplied a NULL pointer for the
> string formatter.
> If glibc does something different than that, glibc is does not have a bug
> either as it is undefined really 
> so converting the call to a puts is a vaild transformation.
> 
Even if its a valid transformation, there is the question if this is a reasonable transformation. Obviously that optimization was introduced because quite alot of people do not know about the puts function and use printf to output static lines of text. On the other hand there are people who rely on glibc's handling of the undefined NULL pointer situation.

Question is: Which group is bigger. The missuse printf as puts group or the rely on glibc's relaxed NULL handling group. My guess would be that people who do not even know puts care even less about the fact that ANSI and ISO didn't care about NULL handling in format strings. If that would true, this optimization would be valid, but unreasonable as it breaks the expections of your clients.

Comment 5 Manuel López-Ibáñez 2007-10-01 09:12:33 UTC
(In reply to comment #4)
> Question is: Which group is bigger. The missuse printf as puts group or the
> rely on glibc's relaxed NULL handling group. My guess would be that people who
> do not even know puts care even less about the fact that ANSI and ISO didn't
> care about NULL handling in format strings. If that would true, this
> optimization would be valid, but unreasonable as it breaks the expections of
> your clients.

The expectations of our "clients" is to follow standards while producing fastest code possible. Glibc behaviour is inconsistent here. In principle there should be no difference between puts(s) and printf("%s",s) and fprintf(stdout, "%s", s). Imagine that the two last ones did something different (I haven't tested, so they actually may) when s == NULL, wouldn't you consider it glibc's fault? Then, why you don't request the same for puts(s)? 
Comment 6 Manuel López-Ibáñez 2007-10-19 14:46:56 UTC
Just for reference. Neither fprintf() nor sprintf() seem to follow the behaviour of printf() in glibc 2.5.