www.digitalmars.com         C & C++   DMDScript  

D - Bug in printf function?

reply "Bruno A. Costa" <bruno codata.com.br> writes:
Hi,

The following code fails to produce the expected result:

// ====================================

import std.string;

int main (char[][] args)
{
        byte bt = 0;
        printf (toString (bt));

        return 0;
}
// ====================================

The printf function should display the string "0", but it shows the sequence
"0123456789". The same thing occurs if I change the value of variable bt to
any number less than 10.

The problem *does not occur* if I concatenate the value returned from
toString with other string:

printf ("Value = " ~ toString(bt)); // Displays "Value = 0" correctly

I am using dmd 0.82 and gcc 3.2.3

cheers.

Bruno.
Apr 26 2004
next sibling parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Bruno A. Costa wrote:

Hi,

The following code fails to produce the expected result:

// ====================================

import std.string;

int main (char[][] args)
{
        byte bt = 0;
        printf (toString (bt));

        return 0;
}
// ====================================
  

printf as well. As a workaround (if it is a bug), you can go: printf (toString (bt).dup); -- -Anderson: http://badmama.com.au/~anderson/
Apr 26 2004
parent reply Ant <Ant_member pathlink.com> writes:
In article <c6ivk0$2roe$1 digitaldaemon.com>, J Anderson says...
Bruno A. Costa wrote:

Hi,

The following code fails to produce the expected result:

// ====================================

import std.string;

int main (char[][] args)
{
        byte bt = 0;
        printf (toString (bt));

        return 0;
}
// ====================================
  

printf as well. As a workaround (if it is a bug), you can go: printf (toString (bt).dup);

(I don't have D here) will it print correctly with printf (toString (bt)~'\0'); // or "\0" ? Ant
Apr 26 2004
parent J Anderson <REMOVEanderson badmama.com.au> writes:
Ant wrote:

(I don't have D here)

will it print correctly with 
printf (toString (bt)~'\0');   // or "\0"
?

Ant

You mean: printf (toString (bt) ~ "\0"); Yeah but: What that's doing is essentially a dup because ~ causes a reallocation of the array with a length. Afterwoods D automatically converts to a zero-terminated string any way. You could add " " on if you wished for the same effect. -- -Anderson: http://badmama.com.au/~anderson/
Apr 26 2004
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Bruno A. Costa wrote:

 Hi,
 
 The following code fails to produce the expected result:

         printf (toString (bt));

Does it work if you do the Right Thing by converting it to a null-terminated string? i.e. printf (toStringz(toString(bt))); Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Apr 26 2004
next sibling parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Stewart Gordon wrote:

 Does it work if you do the Right Thing by converting it to a 
 null-terminated string?  i.e.

     printf (toStringz(toString(bt)));

 Stewart.

That works but as I explained before that causes a reallocation. D automaticly converts char [] to zero terminated string if you pass it into a c char * function. -- -Anderson: http://badmama.com.au/~anderson/
Apr 26 2004
parent Vathix <vathix dprogramming.com> writes:
On Mon, 26 Apr 2004 21:03:02 +0800, J Anderson 
<REMOVEanderson badmama.com.au> wrote:

 Stewart Gordon wrote:

 Does it work if you do the Right Thing by converting it to a 
 null-terminated string?  i.e.

     printf (toStringz(toString(bt)));

 Stewart.

That works but as I explained before that causes a reallocation. D automaticly converts char [] to zero terminated string if you pass it into a c char * function.

toStringz() only reallocates if there's not a zero byte past the end. D will implicitly convert char[] to char*, but whether or not it's zero terminated is up to the caller. This comes up too often ;) -- Christopher E. Miller
Apr 26 2004
prev sibling parent reply "Bruno A. Costa" <bruno codata.com.br> writes:
Stewart Gordon wrote:


 
 Does it work if you do the Right Thing by converting it to a
 null-terminated string?  i.e.
 
 printf (toStringz(toString(bt)));
 
 Stewart.
 

If I do: printf (toString (bt).dup); printf (toStringz(toString (bt))); it works. If I do: printf (toString(125)); // numbers >= 10 don't cause problems it works too, but if I pass a number < 10: printf (toString(5)); // Error: shows 56789 instead of 5. Note that the problem does not seem to be in toString function, because concatenated strings are displayed correctly: printf ("Value = " ~ toString (5)); // Displays "Value = 5" Cheers. Bruno.
Apr 26 2004
next sibling parent Vathix <vathix dprogramming.com> writes:
On Mon, 26 Apr 2004 10:41:13 -0300, Bruno A. Costa <bruno codata.com.br> 
wrote:

 If I do:
         printf (toString (bt).dup);
         printf (toStringz(toString (bt)));

 it works.

 If I do:
         printf (toString(125)); // numbers >= 10 don't cause problems

 it works too, but if I pass a number < 10:

         printf (toString(5)); // Error: shows 56789 instead of 5.

 Note that the problem does not seem to be in toString function, because
 concatenated strings are displayed correctly:

         printf ("Value = " ~ toString (5));   // Displays "Value = 5"

 Cheers.

 Bruno.

D strings aren't always compatible with C strings. They often are, which makes it tricky. Why not use the D function stdout.printf() by importing std.stream and you won't have to worry about it. -- Christopher E. Miller
Apr 26 2004
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Bruno A. Costa wrote:

<snip>
 If I do:
         printf (toString(125)); // numbers >= 10 don't cause problems
 
 it works too, but if I pass a number < 10:
 
         printf (toString(5)); // Error: shows 56789 instead of 5.

That gives insight into how toString works. Obviously it has a string "0123456789" somewhere, and in order to toString a single digit, it just returns a slice of the array. And the length gets lost in the conversion from char[] to char*. This is also consistent with my experience that slices invariably aren't null terminated. At least if they're not at the end of the string, and the string doesn't have an intervening null char in just the right place. OTOH, if the number >= 10, then it builds up the string rather than just cutting a slice. Which, with the way things are implemented, tends to lead to a null termination. Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Apr 26 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:c6j62v$4np$1 digitaldaemon.com...
 That gives insight into how toString works.  Obviously it has a string
 "0123456789" somewhere, and in order to toString a single digit, it just
 returns a slice of the array.  And the length gets lost in the
 conversion from char[] to char*.

You're on to me <g>. One advantage to garbage collection is you don't need to keep track of what is a malloc'd pointer and what is static, they can be mixed up. So, since most conversions are just a single digit, it's very fast to just slice a static array for them. This is one advantage to gc systems that few gc detractors recognize.
Apr 26 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message
news:c6jnbk$13o0$1 digitaldaemon.com...
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:c6j62v$4np$1 digitaldaemon.com...
 That gives insight into how toString works.  Obviously it has a string
 "0123456789" somewhere, and in order to toString a single digit, it just
 returns a slice of the array.  And the length gets lost in the
 conversion from char[] to char*.

You're on to me <g>. One advantage to garbage collection is you don't need to keep track of what is a malloc'd pointer and what is static, they can be mixed up. So, since most conversions are just a single digit, it's very fast to just slice a static array for them. This is one advantage to gc systems that few gc detractors recognize.

Yes indeed. Someone needs to point that out in a book sometime, don't you think?
Apr 26 2004
parent "Walter" <newshound digitalmars.com> writes:
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message
news:c6jrgb$1aln$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message
 news:c6jnbk$13o0$1 digitaldaemon.com...
 "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
 news:c6j62v$4np$1 digitaldaemon.com...
 That gives insight into how toString works.  Obviously it has a string
 "0123456789" somewhere, and in order to toString a single digit, it



 returns a slice of the array.  And the length gets lost in the
 conversion from char[] to char*.

You're on to me <g>. One advantage to garbage collection is you don't


 to keep track of what is a malloc'd pointer and what is static, they can


 mixed up. So, since most conversions are just a single digit, it's very


 to just slice a static array for them. This is one advantage to gc


 that few gc detractors recognize.

Yes indeed. Someone needs to point that out in a book sometime, don't you

LOL!
Apr 26 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"Bruno A. Costa" <bruno codata.com.br> wrote in message
news:c6iumk$2qar$1 digitaldaemon.com...
 Hi,

 The following code fails to produce the expected result:

 // ====================================

 import std.string;

 int main (char[][] args)
 {
         byte bt = 0;
         printf (toString (bt));

         return 0;
 }
 // ====================================

 The printf function should display the string "0", but it shows the

 "0123456789".

That's because toString() creates a D string, whose length is determined by the ".length" property. printf's first argument takes a 0 terminated string. To get what you want, printf("%.*s", toString(bt)); // %.*s will recognize a D string or: printf(toStringz(toString(bt))); // makes a 0 terminated string
Apr 26 2004