At least glibc's printf, maybe others as well, print (null) in for code like printf ("%s", NULL) gcc doesn't consider this when optimizing code where the pointer passed for a %s format specifier can be NULL. Example: #include <stdio.h> int main (int argc, char *argv[]) { printf ("%s\n", argc > 1 ? argv[1] : NULL); return 0; } Compiling and running this code (I use gcc 4.0.2) will result in a program which crashes because the printf is transformed into a puts() call and puts() does not allow NULL pointers. There should at least be a mode in which gcc does not perform the transformation if it cannot be sure the pointer is not NULL. The default for Linux and maybe other platforms should be to not perform this optimization if the pointer can be NULL.
The code is undefined so seg faulting is an okay thing to do.
Reopening to ....
Mark as a dup of bug 15574. *** This bug has been marked as a duplicate of 15574 ***
No, it's *NOT* undefined. The libc interface decides what is defined and what is not and it is *EXPLICITLY* documented that NULL pointers are printed as (null). The standard might leave it undefined but this does *NOT* mean the implementation cannot define it.
You are wrong. *** This bug has been marked as a duplicate of 15685 ***
This is NOT a dup of 15574.
(In reply to comment #4) > The standard might leave it undefined but this does *NOT* mean the > implementation cannot define it. That is true but GCC is a C compiler and not a glibc implemention C compiler.
> That is true but GCC is a C compiler and not a glibc implemention C compiler. This doesn't mean anything. As soon as you configure gcc to target it to Linux the behavior of the runtime is as defined by the C library. gcc doesn't come with it's own C library so it cannot possibly override any decisions made about undefined behavior. I explicitly said that this optimization need ony be disabled for platforms using glibc. I don't give a rats ass what other platforms do.
I should note that glibc is not the world. Also the patch which added the transformations: http://gcc.gnu.org/ml/gcc-patches/2000-09/msg00826.html If you see that RTH approved it without any objections. I still say that this is valid no matter what and people are wrong in assuming that GCC is not going to it as it is undefined code which means depending on it is going to cause portablity issues.
glibc *is* the world as far as Linux is concerned. You consistently and deliberately misinterpret what I write: I'm not talking about any platform which does not use glibc or glibc's behavior. And RTH already concurred in private that this is a problem.
(In reply to comment #10) > glibc *is* the world as far as Linux is concerned. That is not true at all and you know that. There is uclibc. This is still undefined code even if the underlaying printf defines it. This is still a dup of bug 15685 as that is the orginal bug about this issue. *** This bug has been marked as a duplicate of 15685 ***
> That is not true at all and you know that. There is uclibc. Now you've completely given up on logic? First of all, uclibc and whatever other libc immitation is out there does not define the linux API. glibc *is* the world, all the others are just replacements of varying degree of conformance. This can be seen in the fact that even uclibc implements printf with the behavior in question. But more importantly here: even if there were one piece of code which behaves differently, this does not disqualify the argument that the API for Linux defines the behavior in question. This is an OR operation, not AND. glibc defines the behavior and this means the compiler must handle such code approriately if compiled for Linux.
Subject: Re: New: too agressive printf optimization On Fri, 30 Dec 2005, drepper at redhat dot com wrote: > There should at least be a mode in which gcc does not perform the > transformation if it cannot be sure the pointer is not NULL. The default for The mode is -fno-builtin-printf. The same applies for users with custom printf format handlers which modify static variables; they may also need to use -fno-builtin-printf.
Is there any difference in the standard behaviour between printf("%s", NULL) and puts(NULL)? I mean, why printf("%s", NULL) receives special consideration but neither puts(NULL) nor fprintf(stdout, "%s", NULL) do? Anyway, can this be closed as a duplicate of bug 15685 ?
Subject: Re: too agressive printf optimization > Is there any difference in the standard behaviour between printf("%s", NULL) > and puts(NULL)? I mean, why printf("%s", NULL) receives special consideration > but neither puts(NULL) nor fprintf(stdout, "%s", NULL) do? No both are undefined. -- Pinski
"Glibc being Linux being the world" is not really relevant, IMHO. What is relevant is printf() (or any function) is, fundamentally, implemented by library, not by compiler, so compiler should not prevent library from defining behavior not defined in the standard. So I think gcc should either: - provide means to disable printf (or more generaly, any specific function) optimization based on library being linked - not optimize printf in this way, unless requested (i.e. do not include this optimization in any predefined optimizations list - probably other alternatives
This will be fixed yesterday if printf("%s\n", s) were equivalent to puts(s) in glibc. Also there is a way to disable the optimization: "-fno-builtin-printf". People that don't rely on undefined behaviour don't deserve to be punished with suboptimal code.
There is an explanation for the optimisation, a potential fix [*] and there is a workaround. [*] http://sourceware.org/bugzilla/show_bug.cgi?id=5618
(In reply to comment #17) > This will be fixed yesterday if printf("%s\n", s) were equivalent to puts(s) in > glibc. [+] The standard requires them to be equivalent? Per standard, they can't be equivalent if both are undefined when NULL is passed, right? > Also there is a way to disable the optimization: "-fno-builtin-printf". > > People that don't rely on undefined behaviour don't deserve to be punished with > suboptimal code. It is not undefined, per glibc. GCC is defining undefined behavior, just as much as glibc, to optimize, that should be documented or fixed. (In reply to comment #18) > There is an explanation for the optimisation, a potential fix [*] and there is > a workaround. > > [*] http://sourceware.org/bugzilla/show_bug.cgi?id=5618 [+]
(In reply to comment #19) > (In reply to comment #17) > > This will be fixed yesterday if printf("%s\n", s) were equivalent to puts(s) in > > glibc. > > [+] The standard requires them to be equivalent? Per standard, they can't be > equivalent if both are undefined when NULL is passed, right? I didn't say the standard requires them to be equivalent. Per standard, two undefined invocations of printf don't need to be equivalent. Anyway, if you really want to believe that printf("%s\n",s) and puts(s) should not have the same effect for defined behaviour, then we will have to agree to disagree.
(In reply to comment #20) > Anyway, if you really want to believe that printf("%s\n",s) and puts(s) should > not have the same effect for defined behaviour, then we will have to agree to > disagree. That's confused, what is being discussed is undefined behavior X optimization trusting it. Still, the manpage for puts() says "output of characters and strings", while the one for printf() says "formatted output conversion". puts() just sends a string to stdout, printf() converts data into their string representation. So I agree to disagree about the expectation on what they do about NULL: puts() should do nothing or merely return error, while printf() *could* convert or otherwise print a string representation of it. Given the impasse, and given Glibc defines what it does, I understand the next correct thing for someone who cares to do, is to report a bug on GCC about this issue on any specific distributions using GCC together with Glibc. cya
(In reply to comment #21) > (In reply to comment #20) > > Anyway, if you really want to believe that printf("%s\n",s) and puts(s) should > > not have the same effect for defined behaviour, then we will have to agree to > > disagree. > > That's confused, what is being discussed is undefined behavior X optimization > trusting it. No, if we follow your reasoning, as you repeat constantly, "It is not undefined, per glibc." > Still, the manpage for puts() says "output of characters and > strings", while the one for printf() says "formatted output conversion". puts() > just sends a string to stdout, printf() converts data into their string > representation. So I agree to disagree about the expectation on what they do > about NULL: puts() should do nothing or merely return error, while printf() > *could* convert or otherwise print a string representation of it. Finally, we agree about something. :-) Anyway, this has little to do with this bug. This is my personal opinion on how glic could fix if they really wanted. I guess other GCC developers think: "There is nothing to fix, expecting something from undefined behaviour is wrong and the optimisation is valid for all defined cases". > Given the impasse, and given Glibc defines what it does, I understand the next > correct thing for someone who cares to do, is to report a bug on GCC about this > issue on any specific distributions using GCC together with Glibc. What you want us to do? We should avoid optimising printf("%s\n", s) to puts(s) just because s may be NULL? So, in your opinion, we should punish people that don't rely on printf("%s\n", NULL) being defined, and defined as something different as puts(NULL)? Sorry, we disagree. You are welcome to waste your (and others people) time reporting duplicated bugs. We will point them to this discussion. I think there is far enough information here and, in particular, in http://sourceware.org/bugzilla/show_bug.cgi?id=5618 , for anyone to make their own opinion about the issue. If distributions want to patch GCC or use -fno-builtin-printf by default, they are allow to do it. Good luck with that. Please, I am sure you are not that kind of internet character that needs to have the last word on everything, so accept that this is closed. Thanks.
(In reply to Ulrich Drepper from comment #6) > This is NOT a dup of 15574. ok, but related enough to go under "See Also" though