using
Compiler: mingw-gcc-3.4.5 msvcrt60
Executing g++.exe...
i obtained a surprising behaviour of sprintf.
Though norm C98/99 warns about overlapping objects, there is no warning on
overlapping when executing some sprintf(...) applications.
7.19.6.6 The sprintf function
Synopsis
1 #include <stdio.h>
int sprintf(char * restrict s,
const char * restrict format, ...);
Description
2 The sprintf function is equivalent to fprintf, except that the output is
written into
an array (specified by the argument s) rather than to a stream. A null
character is written
at the end of the characters written; it is not counted as part of the
returned value. If
copying takes place between objects that overlap, the behavior is undefined. </stdio.h>
In the following code sequence
rc1 = sprintf( str1, " aaa\n");
rc1 = sprintf( str1, "\n%s bbb\n", str1);
is very different from that one
rc2 = sprintf( str2, " aaa\n\n");
rc2 = sprintf( str2, "%s bbb\n", str2);
Though the second construction well works, the difference is not very
understandable, without the c98/99 norm warning.
Is there a logical explanation here?
See the C-like example
==>code
int main( int argc, char argv, char envp )
{
char str1;
char str2;
int rc1;
int rc2;
Note that Dev-C++ is merely an IDE not a compiler; if you need to know how the
compiler handles such situations the documentation is here. There are many options for controlling
warnings. I suggest that you use at least
-Wformat -Wall -Werror
The MSVCRT library documentation for sprintf() is here.
The "logical explanation" is simply that undefined behaviour is undefined
behaviour. The function need not be coded to deal with the situation in a
consistent manner at all, because the situation would not be considered in its
design.
Moreover within the function, the array arguments will 'decay' to pointers
with no size information so overlapping cannot be detected within the
function.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@finnyalex: You have responded to a great many posts in a very short time. I
suggest that you moderate your activity; many of these threads are old and
have already been adequately answered.
I also suggest that you loose the URL in your signature; many of your posts
look more like an attempt to advertise your site rather than provide useful
content. This particular post is just one such example; you have added no
useful information whatsoever. In fact you simply repeated what I had already
said.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
using
Compiler: mingw-gcc-3.4.5 msvcrt60
Executing g++.exe...
i obtained a surprising behaviour of sprintf.
Though norm C98/99 warns about overlapping objects, there is no warning on
overlapping when executing some sprintf(...) applications.
7.19.6.6 The sprintf function
Synopsis
1 #include <stdio.h>
int sprintf(char * restrict s,
const char * restrict format, ...);
Description
2 The sprintf function is equivalent to fprintf, except that the output is
written into
an array (specified by the argument s) rather than to a stream. A null
character is written
at the end of the characters written; it is not counted as part of the
returned value. If
copying takes place between objects that overlap, the behavior is undefined. </stdio.h>
In the following code sequence
rc1 = sprintf( str1, " aaa\n");
rc1 = sprintf( str1, "\n%s bbb\n", str1);
is very different from that one
rc2 = sprintf( str2, " aaa\n\n");
rc2 = sprintf( str2, "%s bbb\n", str2);
Though the second construction well works, the difference is not very
understandable, without the c98/99 norm warning.
Is there a logical explanation here?
See the C-like example
==>code
int main( int argc, char argv, char envp )
{
char str1;
char str2;
int rc1;
int rc2;
/ case 1 /
fprintf(stdout, " --> case 1\n");
memset( str1, 0, sizeof( str1)) ;
rc1 = sprintf( str1, " aaa\n");
fprintf( stdout, " rc1 = %d ( executing : rc1 = sprintf( str1, \"
aaa\n\");)\n", rc1);
image_zone( ( unsigned char ) str1 , sizeof( str1) , 16, -1L, "str1",
stdout);
rc1 = sprintf( str1, "\n%s bbb\n", str1);
fprintf( stdout, " rc1 = %d ( executing : rc1 = sprintf( str1, \"\n%%s
bbb\n\", str1);)\n", rc1);
image_zone( ( unsigned char ) str1 , sizeof( str1) , 16, -1L, "str1",
stdout);
rc1 = sprintf( str1, "%s ccc.", str1);
fprintf( stdout, " rc1 = %d ( executing : rc1 = sprintf( str1, \"%%s ccc.\",
str1);)\n", rc1);
image_zone( ( unsigned char *) str1 , sizeof( str1) , 16, -1L, "str1",
stdout);
fprintf( stdout, "\n%s\n", str1);
fprintf(stdout, "--------------------------------------------------------\n");
/ case 2 /
fprintf(stdout, " --> case 2\n");
memset( str2, 0, sizeof( str2)) ;
rc2 = sprintf( str2, " aaa\n\n");
fprintf( stdout, " rc2 = %d ( executing : rc2 = sprintf( str2, \"
aaa\n\n\");)\n", rc2);
image_zone( ( unsigned char ) str2 , sizeof( str2) , 16, -1L, "str2",
stdout);
rc2 = sprintf( str2, "%s bbb\n", str2);
fprintf( stdout, " rc2 = %d ( executing : rc2 = sprintf( str2, \"%%s bbb\n\",
str2);)\n", rc2);
image_zone( ( unsigned char ) str2 , sizeof( str2) , 16, -1L, "str2",
stdout);
rc2 = sprintf( str2, "%s ccc.", str2);
fprintf( stdout, " rc2 = %d ( executing : rc2 = sprintf( str2, \"%%s ccc.\",
str2);)\n", rc2);
image_zone( ( unsigned char *) str2 , sizeof( str2) , 16, -1L, "str2",
stdout);
fprintf( stdout, "\n%s\n", str2);
exit( 0);
} / int main( int argc, char argv, char envp ) /
==>output
. --> case 1
. rc1 = 5 ( executing : rc1 = sprintf( str1, " aaa\n");)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff50" : "str1"
. 0023ff50 .. 20616161 0a000000 00000000 00000000 . aaa
. 0023ff60 .. 00000000 00000000 00000000 00000000 .
. rc1 = 12 ( executing : rc1 = sprintf( str1, "\n%s bbb\n", str1);)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff50" : "str1"
. 0023ff50 .. 0a0a0a0a 0a0a2020 6262620a 00000000 . bbb
. 0023ff60 .. 00000000 00000000 00000000 00000000 .
. rc1 = 18 ( executing : rc1 = sprintf( str1, "%s ccc.", str1);)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff50" : "str1"
. 0023ff50 .. 0a0a0a0a 0a0a2020 6262620a 20206363 . bbb cc
. 0023ff60 .. 632e0000 00000000 00000000 00000000 . c.
.
.
.
.
.
.
.
. bbb
. ccc.
.--------------------------------------------------------
. --> case 2
. rc2 = 6 ( executing : rc2 = sprintf( str2, " aaa\n\n");)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff30" : "str2"
. 0023ff30 .. 20616161 0a0a0000 00000000 00000000 . aaa
. 0023ff40 .. 00000000 00000000 00000000 00000000 .
. rc2 = 12 ( executing : rc2 = sprintf( str2, "%s bbb\n", str2);)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff30" : "str2"
. 0023ff30 .. 20616161 0a0a2020 6262620a 00000000 . aaa bbb
. 0023ff40 .. 00000000 00000000 00000000 00000000 .
. rc2 = 18 ( executing : rc2 = sprintf( str2, "%s ccc.", str2);)
. image en base 16 ( groupes de 4 octets, 2 caracteres par octet) de la zone
. "0x0023ff30" : "str2"
. 0023ff30 .. 20616161 0a0a2020 6262620a 20206363 . aaa bbb cc
. 0023ff40 .. 632e0000 00000000 00000000 00000000 . c.
.
. aaa
.
. bbb
. ccc.
Is there a question in there somewhere?
Post your code in code markup!
Note that Dev-C++ is merely an IDE not a compiler; if you need to know how the
compiler handles such situations the documentation is
here. There are many options for controlling
warnings. I suggest that you use at least
The MSVCRT library documentation for sprintf() is
here.
The "logical explanation" is simply that undefined behaviour is undefined
behaviour. The function need not be coded to deal with the situation in a
consistent manner at all, because the situation would not be considered in its
design.
Moreover within the function, the array arguments will 'decay' to pointers
with no size information so overlapping cannot be detected within the
function.
@finnyalex: You have responded to a great many posts in a very short time. I
suggest that you moderate your activity; many of these threads are old and
have already been adequately answered.
I also suggest that you loose the URL in your signature; many of your posts
look more like an attempt to advertise your site rather than provide useful
content. This particular post is just one such example; you have added no
useful information whatsoever. In fact you simply repeated what I had already
said.