Thread View: gnu.gcc.bug
7 messages
7 total messages
Started by Volker Luckas
Thu, 05 Dec 1996 00:00
Why is this possible?
Author: Volker Luckas
Date: Thu, 05 Dec 1996 00:00
Date: Thu, 05 Dec 1996 00:00
36 lines
1543 bytes
1543 bytes
Hello all,
it was very astonishing for me to recognize that the following piece of
source code is accepted by gcc 2.7.2 (Solaris 2.5) without giving a
warning if gcc is called in the following way:
gcc test.c -o test
#include <string.h>
int main( )
{
char* str = "0.12345678";
double val = 1.11111111;
sprintf( str, "%lf", val );
printf( "Result: %s\n", str );
return 0;
}
The generated binary crashes if started afterwards. Interestingly this
does not happen if you compile the source with cc from the Solaris 2.5
Compiler package or even with gcc 2.7.2 running under IRIX 5.3
Compiling the source with -Wall gives you a warning about implicitely
defined functions but no warning about the illegal sprintf( ) call.
Is there any possibility to avoid this kind of behaviour ???
--
(o o)
---ooO--(_)--Ooo---
Greetings Volker (luckas@igd.fhg.de)
Re: Why is this possible?
Author: Hardy Griech
Date: Thu, 05 Dec 1996 00:00
Date: Thu, 05 Dec 1996 00:00
24 lines
1317 bytes
1317 bytes
On Thu, 05 Dec 1996 09:28:36 +0100, luckas@igd.fhg.de (Volker Luckas) wrote: > Hello all, > > it was very astonishing for me to recognize that the following piece of > source code is accepted by gcc 2.7.2 (Solaris 2.5) without giving a > warning if gcc is called in the following way: : Just use the -Wall option and you will get the following output: [C:\tmp]gcc -Wall -o test.exe test.c test.c: In function `main': test.c:8: warning: implicit declaration of function `sprintf' test.c:8: warning: use of `l' length character with `f' type character test.c:10: warning: implicit declaration of function `printf' [C:\tmp]gcc -v gcc version 2.7.2.1 This all happened on OS/2 with emx09c. -- Hardy Griech, Kurt-Schumacher-Str. 25/1, D-72762 Reutlingen
Re: Why is this possible?
Author: Alex Martelli
Date: Fri, 06 Dec 1996 00:00
Date: Fri, 06 Dec 1996 00:00
60 lines
2671 bytes
2671 bytes
luckas@igd.fhg.de (Volker Luckas) writes:
>it was very astonishing for me to recognize that the following piece of
>source code is accepted by gcc 2.7.2 (Solaris 2.5) without giving a
>warning if gcc is called in the following way:
I'm not sure why this should be "astonishing", actually.
>gcc test.c -o test
>#include <string.h>
>int main( )
>{
> char* str = "0.12345678";
> double val = 1.11111111;
> sprintf( str, "%lf", val );
> printf( "Result: %s\n", str );
> return 0;
>}
>The generated binary crashes if started afterwards. Interestingly this
>does not happen if you compile the source with cc from the Solaris 2.5
>Compiler package or even with gcc 2.7.2 running under IRIX 5.3
>Compiling the source with -Wall gives you a warning about implicitely
>defined functions but no warning about the illegal sprintf( ) call.
There is nothing illegal about that sprintf() call -- just the
questionable use of "%lf", and you do get a warning about that
one with -Wall. sprintf() takes as its first argument a char*,
you are supplying it with a char*, what's illegal about that?
What is, not illegal, but VERY questionable, is initializing a
char* to a literal character string; however, the ANSI C standard
deems that to be legal. If the first line was something like:
char * str = (char*)123456;
you wouldn't be particularly astonished to see the resulting
program crash in some cases and not in others, would you? At
least, I wouldn't be.
>Is there any possibility to avoid this kind of behaviour ???
You can add the -Wwrite-strings flag to your compilation line
in order to make a literal character string evaluate to a
const char *, rather than to a char * as the ANSI C standard
mandates. If you do that, you'll get a warning about const
being implicitly cast away in the "char* str = ..." line.
Alex
--
DISCLAIMER: these are MY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it -- Phone: +39 (51) 597 313 [Fax: 597 120]
Cad.Lab S.p.A., v. Ronzani 7/29, 40033 Casalecchio (BO), Italia
Re: Why is this possible?
Author: Martin Huber
Date: Sun, 08 Dec 1996 00:00
Date: Sun, 08 Dec 1996 00:00
45 lines
2203 bytes
2203 bytes
In article <32A687B4.430F@igd.fhg.de>, luckas@igd.fhg.de (Volker Luckas) writes:
>Hello all,
>
>it was very astonishing for me to recognize that the following piece of
>source code is accepted by gcc 2.7.2 (Solaris 2.5)
>
>
> .. snip ...
>
>int main( )
>{
> char* str = "0.12345678";
> double val = 1.11111111;
>
> sprintf( str, "%lf", val );
>
> printf( "Result: %s\n", str );
>
> return 0;
>}
>
>The generated binary crashes if started afterwards. Interestingly this
>does not happen if you compile the source with cc from the Solaris 2.5
>Compiler package or even with gcc 2.7.2 running under IRIX 5.3
>
>Compiling the source with -Wall gives you a warning about implicitely
>defined functions but no warning about the illegal sprintf( ) call.
>
gcc is doing right. str is a pointer to an array of characters, and
sprintf() is intended to print to a character array. The bug is, that
you initialized str to point to a fixed string. This is placed by the
compiler into the data segment instead of the segment of uninitialized
data. gcc does not allow to write to initialized strings as default,
and since it can't see at compile-time to what value str will point
during the program execution, it can't give a warning, but will crash
at runtime to show you the bug in the corefile.
Not all compilers do so. Your example should run if you call gcc with
the option -fwritable-strings if you require it. But note, that this
is prone to errors, since you allocate the size of the array by the
length of your string. If sprintf() writes a longer string, you will
get unpredictable results.
Martin
Re: Why is this possible?
Author: Martin Huber
Date: Sun, 08 Dec 1996 00:00
Date: Sun, 08 Dec 1996 00:00
47 lines
2271 bytes
2271 bytes
In article <32A687B4.430F@igd.fhg.de>, luckas@igd.fhg.de (Volker Luckas) writes:
>Hello all,
>
>it was very astonishing for me to recognize that the following piece of
>source code is accepted by gcc 2.7.2 (Solaris 2.5) without giving a
>warning if gcc is called in the following way:
>
>gcc test.c -o test
>
>#include <string.h>
>
>int main( )
>{
> char* str = "0.12345678";
> double val = 1.11111111;
>
> sprintf( str, "%lf", val );
>
> printf( "Result: %s\n", str );
>
> return 0;
>}
>
>The generated binary crashes if started afterwards. Interestingly this
>does not happen if you compile the source with cc from the Solaris 2.5
>Compiler package or even with gcc 2.7.2 running under IRIX 5.3
>
>Compiling the source with -Wall gives you a warning about implicitely
>defined functions but no warning about the illegal sprintf( ) call.
>
The call to sprintf is not illegal. str is a pointer to a character
array, and sprintf is intended to print into it.
The bug is that you initialize str to a fixed string "...", which is
located in the initialized data segment. As default, gcc goes not allow
to overwrite it, and since there is no way to detect at compile time where
your pointer str will point to during execution (a pointer may change!),
gcc can't give a warning, but the program will crash at runtime to show
you the error in the corefile (or gdb).
Not all compilers do so. If you need this behaviour, use
gcc -fwritable-strings
and your example should run. But notice that you are inviting trouble
doing so. The size of str is defined by the length of "...", and if
the string produced by sprintf() is longer you get unpredictible results.
Martin
Re: Why is this possible?
Author: Xavier Sunyer. PFC
Date: Wed, 11 Dec 1996 00:00
Date: Wed, 11 Dec 1996 00:00
22 lines
1599 bytes
1599 bytes
Hello: I'm using gcc2.6.3 under SunOS4.1.4. About the implicit declarations warnings, two comments: - sprintf() and printf() prototypes are declared (ANSI) in stdio.h; therefore you should include this header instead of string.h. - it may be that this change do not eliminates the printf() warning; I've found that printf's prototype -among others- is only declared if the macro __USE_FIXED_PROTOTYPES__ is set. Then you can compile with -D__USE_FIXED_PROTOTYPES__ or add this line to your 'specs' file (you can locate it compiling with -v). About the bug reason, I'm agree with Martin Huber. To detect it, I suggest you to declare 'const char *str = "0.12345678' -I suppose you want const objects really be constant-. If you do this, during the compilation you'll have the warning "passing arg 1 of `sprintf' discards `const' from pointer target type". Victor Sune UPC sunye@eel.upc.es
Re: Why is this possible?
Author: Xavier Sunyer. PFC
Date: Wed, 11 Dec 1996 00:00
Date: Wed, 11 Dec 1996 00:00
22 lines
1599 bytes
1599 bytes
Hello: I'm using gcc2.6.3 under SunOS4.1.4. About the implicit declarations warnings, two comments: - sprintf() and printf() prototypes are declared (ANSI) in stdio.h; therefore you should include this header instead of string.h. - it may be that this change do not eliminates the printf() warning; I've found that printf's prototype -among others- is only declared if the macro __USE_FIXED_PROTOTYPES__ is set. Then you may compile with -D__USE_FIXED_PROTOTYPES__ or add this line to your 'specs' file (you can locate it compiling with -v). About the bug reason, I'm agree with Martin Huber. To detect it, I suggest you to declare 'const char *str = "0.12345678' -I suppose you want const objects really be constant-. If you do this, during the compilation you'll have the warning "passing arg 1 of `sprintf' discards `const' from pointer target type". Victor Sune UPC sunye@eel.upc.es
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads