Format problem with sprintf

H

Henryk

Hey there,

I have some problems with the following code snippet on a Virtex-4
PowerPC with a GCC based compiler

char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -0.380f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -3.800f); --> I get "-0004" ok
sprintf(&chData[0], "%+05.0f", +0.038f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +0.380f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +3.800f); --> I get "+0004" ok

I would expect to get always a string with the length of 5 but
sometimes I get only 4 chars back. Is this a compiler bug?

In Visual Studio I get always 5 chars back.

Thank you

Henryk
 
M

Mike Wahler

Henryk said:
Hey there,

I have some problems with the following code snippet on a Virtex-4
PowerPC with a GCC based compiler

char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -0.380f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -3.800f); --> I get "-0004" ok
sprintf(&chData[0], "%+05.0f", +0.038f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +0.380f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +3.800f); --> I get "+0004" ok

I would expect to get always a string with the length of 5 but
sometimes I get only 4 chars back. Is this a compiler bug?

In Visual Studio I get always 5 chars back.

Me too (VC++ 2005 Express). Perhaps there is a problem with
your compiler. Try checking its support resources. We only
discuss the C language itself here, not specific implementations.

FWIW, I've included my test program and its output (which looks
correct) below.


-Mike

#include <string.h>
#include <stdio.h>

int main(void)
{
char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); /* --> I get "-000" ??? */
printf("%s\n", chData);

sprintf(&chData[0], "%+05.0f", -0.380f); /* --> I get "-000" ??? */
printf("%s\n", chData);

sprintf(&chData[0], "%+05.0f", -3.800f); /* --> I get "-0004" ok */
printf("%s\n", chData);

sprintf(&chData[0], "%+05.0f", +0.038f); /* --> I get "+000" ??? */
printf("%s\n", chData);

sprintf(&chData[0], "%+05.0f", +0.380f); /* --> I get "+000" ??? */
printf("%s\n", chData);

sprintf(&chData[0], "%+05.0f", +3.800f); /* --> I get "+0004" ok */
printf("%s\n", chData);

return 0;
}

Output:

-0000
-0000
-0004
+0000
+0000
+0004

-Mike
 
C

Christopher Benson-Manica

Mike Wahler said:
Me too (VC++ 2005 Express). Perhaps there is a problem with
your compiler. Try checking its support resources. We only
discuss the C language itself here, not specific implementations.

I do think it's on-topic to essentially ask whether the behavior of a
particular implementation is conformant; in this case, the answer WRT
OP's implementation is presumably "no". Not that VC++ should be held
up as a standard of correctness of course :)
 
M

Martin Ambuhl

Henryk said:
Hey there,

I have some problems with the following code snippet on a Virtex-4
PowerPC with a GCC based compiler

I don't know what a "Gcc based compiler" means. My gcc compiler does
not reproduce the behavior you report. The behavior you report is not,
in any case, a question of the compiler but of a supplied library.
Replace your version of the C library with one that does not have broken
*printf functions.
char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -0.380f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -3.800f); --> I get "-0004" ok
sprintf(&chData[0], "%+05.0f", +0.038f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +0.380f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +3.800f); --> I get "+0004" ok

I would expect to get always a string with the length of 5 but
sometimes I get only 4 chars back. Is this a compiler bug?

In Visual Studio I get always 5 chars back.

The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.

#include <stdio.h>
int main(void)
{
char chData[6];

sprintf(chData, "%+05.0f", -0.038f);
printf("%s\n", chData);
sprintf(chData, "%+05.0f", -0.380f);
printf("%s\n", chData);
sprintf(chData, "%+05.0f", -3.800f);
printf("%s\n", chData);
sprintf(chData, "%+05.0f", +0.038f);
printf("%s\n", chData);
sprintf(chData, "%+05.0f", +0.380f);
printf("%s\n", chData);
sprintf(chData, "%+05.0f", +3.800f);
printf("%s\n", chData);
return 0;
}


-0000
-0000
-0004
+0000
+0000
+0004
 
R

Robert Gamble

Henryk said:
Hey there,

I have some problems with the following code snippet on a Virtex-4
PowerPC with a GCC based compiler

char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -0.380f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -3.800f); --> I get "-0004" ok
sprintf(&chData[0], "%+05.0f", +0.038f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +0.380f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +3.800f); --> I get "+0004" ok

I would expect to get always a string with the length of 5 but
sometimes I get only 4 chars back. Is this a compiler bug?

In Visual Studio I get always 5 chars back.

The output you describe in your example is not Standard conforming. As
for whether this is a compiler issue or a library implementation issue,
try compiling with the gcc option --no-builtin-sprintf and see if you
get the same results; if you do it is a libc issue, otherwise it is an
issue with the gcc built-in function (or else they are both broken).

Robert Gamble
 
J

jacob navia

Henryk said:
Hey there,

I have some problems with the following code snippet on a Virtex-4
PowerPC with a GCC based compiler

char chData[6];

sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -0.380f); --> I get "-000" ???
sprintf(&chData[0], "%+05.0f", -3.800f); --> I get "-0004" ok
sprintf(&chData[0], "%+05.0f", +0.038f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +0.380f); --> I get "+000" ???
sprintf(&chData[0], "%+05.0f", +3.800f); --> I get "+0004" ok

I would expect to get always a string with the length of 5 but
sometimes I get only 4 chars back. Is this a compiler bug?

In Visual Studio I get always 5 chars back.

Thank you

Henryk
I tested it with lcc-win32 and got the same results as with
MSVC.

Using gcc under linux I get the same results as MSVC
and lcc-win32.

gcc -v gives:
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)

In another linux machine I got the same result.
gcc -v gives in that machine:
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--host=i386-redhat-linux
Thread model: posix
gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)


I think this is not a gcc problem
 
H

Henryk

The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.

The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning). Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)

Greets

Henryk
 
H

Henryk

Christopher said:
I do think it's on-topic to essentially ask whether the behavior of a
particular implementation is conformant; in this case, the answer WRT
OP's implementation is presumably "no". Not that VC++ should be held
up as a standard of correctness of course :)


Thank you. I will report this possible bug to Xilinx.

Henryk
 
C

CBFalconer

Henryk said:
The following code (and a version with the silly "&chData[0]" for
plain "chData") give, with gcc, the output following it.

The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning). Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)

Please don't remove attribution lines for material you quote.
Attribution lines are the ones that say "whozit wrote:".

chData and &chData[0] are entirely different things. In some cases
the passed specification for each may be identical, but that is a
coincidence, not a necessity.

chData is (presumably) an array of some type. &chData[0] is a
pointer to the first item in that array. The difference will be
dramatic if you simply display:

printf("sz(chData)=%ld, sz(&chData[0]=%ld\n",
(long)sizeof(chData), (long)sizeof(&chData[0]));
 
B

Ben Pfaff

Henryk said:
The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.

The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning).

If chData is declared as array of char, then &chData[0] and
chData have the same type and value. It is surprising that a
compiler would warn about the former and not the latter.
Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)

We discuss C here. C doesn't have static_cast.
 
M

Martin Ambuhl

Henryk said:
The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.

The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning). Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)

Henryk, who is a Googlegroups (ab)user, has kept from you the context,
which was my substitution (in compilable code) of
sprintf(chData, "%+05.0f", -0.038f);
for his (in uncompilable single lines)
sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
where he has defined
char chData[6];

While your compiler is free to issue whatever bogus diagnostics its
writers want it to, no sane writer of a C compiler would issue one in
this case. It is more likely that
a) your compiler is broken or
b) your compiler is not a C compiler (and so broken for compiling C).
In fact, your reference to the completely undefined identifier from the
programmer's namespace of "static_cast" suggests that you are using a
C++ compiler. If you continue to have C++ questions, the newsgroup for
that different language is < This newsgroup is for
C, and none of your comments is relevant to that language.
 
H

Henryk

Martin said:
Henryk said:
The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.

The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning). Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)

Henryk, who is a Googlegroups (ab)user, has kept from you the context,
which was my substitution (in compilable code) of
sprintf(chData, "%+05.0f", -0.038f);
for his (in uncompilable single lines)
sprintf(&chData[0], "%+05.0f", -0.038f); --> I get "-000" ???
where he has defined
char chData[6];

While your compiler is free to issue whatever bogus diagnostics its
writers want it to, no sane writer of a C compiler would issue one in
this case. It is more likely that
a) your compiler is broken or
b) your compiler is not a C compiler (and so broken for compiling C).
In fact, your reference to the completely undefined identifier from the
programmer's namespace of "static_cast" suggests that you are using a
C++ compiler. If you continue to have C++ questions, the newsgroup for
that different language is < This newsgroup is for
C, and none of your comments is relevant to that language.

I asked the C newsgroup because sprintf is part of ANSI C. Sorry for
the fauxpas with the static_cast. I usually write C++ code. And even if
it is a C++ compiler sprintf should behave according to ANSI C.

Henryk
 
M

Martin Ambuhl

Henryk wrote (in response to my comments which I have snipped away):
Henryk said:
The following code (and a version with the silly "&chData[0]" for plain
"chData") give, with gcc, the output following it.
The "silly" &chData[0] is used to avoid compiler errors/warnings on
higher warning levels (something like casting array to pointer
warning). Of course I could use some static_cast too to avoid the
warning. But that takes longer to write... ;o)
I asked the C newsgroup because sprintf is part of ANSI C. Sorry for
the fauxpas with the static_cast. I usually write C++ code. And even if
it is a C++ compiler sprintf should behave according to ANSI C.

You are confused. The question of whether '&chData[0]' is somehow
preferable as the first argument to sprintf to the straight-forward,
100% legal C approach of using unadorned 'chData' has nothing to do with
the way sprintf behaves. If unadorned 'chData' leads to legitimate
warnings from your compiler, it is because your compiler has some
restriction that is completely non-C on arguments.

Now, the current version of C, now zeven years old, has this as the
prototype for sprintf:
int sprintf(char * restrict s, const char * restrict format, ...);

If the language that your compiler is using does not understand
'restrict', then it clearly cannot handle a type of 'char * restrict'.
In fact, C++ does not know anything about 'restrict', so must use the
older form of sprintf. if it uses a C version at all. That prototype is
int sprintf(char *s, const char *format, ...);
If your compiler does not accept unadorned 'chData' ( declared as a
char[6], in your case) as appropriate for a parameter of type 'char *',
it will reject it for _all_ such functions, whether they are part of the
library or written by you. This has _nothing_ to do with sprintf except
for the types of arguments. If you are using C++ and it is broken in
this way, so much the worse for C++ and those forced to use it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top