digitalmars.D.bugs - printf bugs
- Sean Kelly (22/22) Jul 01 2004 You probably already know these, but I thought I'd report them anyway. ...
- Ben Hinkle (11/33) Jul 01 2004 well... these aren't really bugs since printf is doing exactly what it i...
- Sean Kelly (7/13) Jul 01 2004 Good point. I just downloaded 0.94 and floating point has completely ch...
- Sean Kelly (6/9) Jul 01 2004 Just to be picky, %f is actually for type "double," at least according t...
- Ben Hinkle (3/18) Jul 01 2004 oh yeah. duh. for some reason I was thinking of scanf. maybe because of ...
- Walter (7/29) Jul 02 2004 Reals in D correspond to long doubles in C, which means you need to be u...
- Sean Kelly (20/22) Jul 02 2004 Thanks. Talking to Ben made me realize the problem with reals. But tha...
- Regan Heath (31/66) Jul 02 2004 The new printf would not necessarily have to even use %s %S %d %l etc.. ...
- Daniel Horn (3/41) Jul 02 2004 Now that would make quick and dirty printf programs really fun to write ...
- Sean Kelly (9/27) Jul 02 2004 I see two problems with this. First, as per my post I don't know if
- Regan Heath (11/38) Jul 03 2004 I was wondering the same thing, however, do you ever need to
- Sean Kelly (15/34) Jul 03 2004 How each type is handled is different. D arrays have a length specifier...
- Regan Heath (12/45) Jul 03 2004 Ahh.. I see.. you were talking about the value of the array, not the
- Juliano Ravasi Ferraz (17/19) Jul 03 2004 What if we have more than 9 arguments? "$10" is the 10th argument or the...
- Regan Heath (39/55) Jul 03 2004 The way the original printf avoids this problem is that when it uses
- Sean Kelly (33/33) Jul 04 2004 In 0.93, the code:
- J C Calvarese (9/42) Jul 04 2004 Why are you using "%i"? What does it mean? (Maybe it needs to be added t...
- Regan Heath (33/84) Jul 05 2004 It's identical to %d. (according to MSDN)
- Arcane Jill (5/9) Jul 05 2004 Right, so the only way it can ever become obsolete is if something even ...
- Regan Heath (7/18) Jul 05 2004 Yeah, I know.. the posts on the new printf seem promising. IMO TypeInfo
You probably already know these, but I thought I'd report them anyway. The code: prints: 1 0.000000 0.000000 1.000000 -0.000000 real == 2.0 real Error: Access Violation There are a few things going on here. Real always prints as -0.0, floats print as 0.0 if they aren't the first element in the format string, and strings are a tad broken :)
Jul 01 2004
well... these aren't really bugs since printf is doing exactly what it is supposed to do. Maybe I'm being too picky about the word "bug" (for example %f is only for type "float" not "double" or "real"). Walter said he is writing a printf replacement and since vararg functions can detect the types of the inputs the format strings will presumably become much simpler - if there are format strings at all. "Sean Kelly" <sean f4.ca> wrote in message news:cc1qqb$2dq7$1 digitaldaemon.com...You probably already know these, but I thought I'd report them anyway.Thecode: prints: 1 0.000000 0.000000 1.000000 -0.000000 real == 2.0 real Error: Access Violation There are a few things going on here. Real always prints as -0.0, floatsprintas 0.0 if they aren't the first element in the format string, and stringsare atad broken :)
Jul 01 2004
In article <cc1suk$2gkq$1 digitaldaemon.com>, Ben Hinkle says...well... these aren't really bugs since printf is doing exactly what it is supposed to do. Maybe I'm being too picky about the word "bug" (for example %f is only for type "float" not "double" or "real"). Walter said he is writing a printf replacement and since vararg functions can detect the types of the inputs the format strings will presumably become much simpler - if there are format strings at all.Good point. I just downloaded 0.94 and floating point has completely changed for this input set. The bad news is that it doesn't work at all now :) I think I'm going to roll back to a previous version of the compiler and wait until printf is finished before moving forward. Is there a place where old builds are stored? I couldn't find one on the FTP site. Sean
Jul 01 2004
In article <cc1suk$2gkq$1 digitaldaemon.com>, Ben Hinkle says...well... these aren't really bugs since printf is doing exactly what it is supposed to do. Maybe I'm being too picky about the word "bug" (for example %f is only for type "float" not "double" or "real").Just to be picky, %f is actually for type "double," at least according to the C99 standard. But if D had been calling the Windows version of printf then it's quite possible their version just has different/older rules. I know I've found quite a few discrepancies with scanf. Sean
Jul 01 2004
Sean Kelly wrote:In article <cc1suk$2gkq$1 digitaldaemon.com>, Ben Hinkle says...oh yeah. duh. for some reason I was thinking of scanf. maybe because of the recent scanf + complex question. oh well!well... these aren't really bugs since printf is doing exactly what it is supposed to do. Maybe I'm being too picky about the word "bug" (for example %f is only for type "float" not "double" or "real").Just to be picky, %f is actually for type "double," at least according to the C99 standard.But if D had been calling the Windows version of printf then it's quite possible their version just has different/older rules. I know I've found quite a few discrepancies with scanf. Sean
Jul 01 2004
Reals in D correspond to long doubles in C, which means you need to be using %Lf, not %f, to print them. Next, for strings use %.*s, not %s. "Sean Kelly" <sean f4.ca> wrote in message news:cc1qqb$2dq7$1 digitaldaemon.com...You probably already know these, but I thought I'd report them anyway.Thecode: prints: 1 0.000000 0.000000 1.000000 -0.000000 real == 2.0 real Error: Access Violation There are a few things going on here. Real always prints as -0.0, floatsprintas 0.0 if they aren't the first element in the format string, and stringsare atad broken :)
Jul 02 2004
In article <cc3782$1idh$1 digitaldaemon.com>, Walter says...Reals in D correspond to long doubles in C, which means you need to be using %Lf, not %f, to print them. Next, for strings use %.*s, not %s.Thanks. Talking to Ben made me realize the problem with reals. But thanks to the nifty new _arguments stuff, I suspect it won't be a problem for long :) I'm having issues with normal doubles in 0.94, but I suspect this is because the new version of printf is incomplete, since the version in 0.93 worked just fine. This is a related issue I ran into writing scanf. The %s parameter currently accepts both C strings and D strings. I had tried this to differentiate between them: if( _arguments[arg] == typeid( char[]* ) ) // D string else if( _arguments[arg] == typeid( char** ) ) // C string But both typeids are equivalent--the first condition is called for both D and C strings. And if I reverse them then the new first condition (char**) is called for both. Is there any way to tell the difference between D and C strings using the typeid code (or really pointers to D and C strings, since I can't deref a void pointer)? Assuming there isn't, I propose adding an extension to printf (%S) that corresponds to D strings. I've already added this to scanf, since the %.*s syntax doesn't make sense in this context. Sean
Jul 02 2004
On Fri, 2 Jul 2004 18:56:40 +0000 (UTC), Sean Kelly <sean f4.ca> wrote:In article <cc3782$1idh$1 digitaldaemon.com>, Walter says...The new printf would not necessarily have to even use %s %S %d %l etc.. in fact why should you need to tell it what type the arguments are at all? it already knows! IMO the new printf should work something like this... int a; long b; real c; printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c); or similar, basically you specify the position of the arg to use, this allows this also: printf("regan was $1 and also $1 again",a); *if* you/walter are worried about compatibilty, then lets have a printf that works like the C one, but also a new variant that works something like I have described, simply call it 'print' perhaps. the above proposal would be incomplete without the ability to print a type like another type, so for example if you want to print a char like an int, then you can use a cast i.e. char c; printf("regan was $1",cast(int)c); Something just occured to me, if you say printf("regan was $1",&c); (like in C printf("%p",&c) or printf("%x",&c); what TypeInfo does printf get? it's the address of a char, is that ever going to be handled differently to the address of a long or real or.. so should the TypeInfo be "char *" or should it simply tell you it's an "l-value"? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/Reals in D correspond to long doubles in C, which means you need to be using %Lf, not %f, to print them. Next, for strings use %.*s, not %s.Thanks. Talking to Ben made me realize the problem with reals. But thanks to the nifty new _arguments stuff, I suspect it won't be a problem for long :) I'm having issues with normal doubles in 0.94, but I suspect this is because the new version of printf is incomplete, since the version in 0.93 worked just fine. This is a related issue I ran into writing scanf. The %s parameter currently accepts both C strings and D strings. I had tried this to differentiate between them: if( _arguments[arg] == typeid( char[]* ) ) // D string else if( _arguments[arg] == typeid( char** ) ) // C string But both typeids are equivalent--the first condition is called for both D and C strings. And if I reverse them then the new first condition (char**) is called for both. Is there any way to tell the difference between D and C strings using the typeid code (or really pointers to D and C strings, since I can't deref a void pointer)? Assuming there isn't, I propose adding an extension to printf (%S) that corresponds to D strings. I've already added this to scanf, since the %.*s syntax doesn't make sense in this context.
Jul 02 2004
Now that would make quick and dirty printf programs really fun to write :-) and the translator folks would love it! Regan Heath wrote:IMO the new printf should work something like this... int a; long b; real c; printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c); or similar, basically you specify the position of the arg to use, this allows this also: printf("regan was $1 and also $1 again",a); *if* you/walter are worried about compatibilty, then lets have a printf that works like the C one, but also a new variant that works something like I have described, simply call it 'print' perhaps. the above proposal would be incomplete without the ability to print a type like another type, so for example if you want to print a char like an int, then you can use a cast i.e. char c; printf("regan was $1",cast(int)c); Something just occured to me, if you say printf("regan was $1",&c); (like in C printf("%p",&c) or printf("%x",&c); what TypeInfo does printf get? it's the address of a char, is that ever going to be handled differently to the address of a long or real or.. so should the TypeInfo be "char *" or should it simply tell you it's an "l-value"? Regan.
Jul 02 2004
Regan Heath wrote:The new printf would not necessarily have to even use %s %S %d %l etc.. in fact why should you need to tell it what type the arguments are at all? it already knows! IMO the new printf should work something like this... int a; long b; real c; printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c); or similar, basically you specify the position of the arg to use, this allows this also: printf("regan was $1 and also $1 again",a);I see two problems with this. First, as per my post I don't know if there's any way to differentiate between a dynamic D array and a pointer to a sequence of the same type. Hopefully Walter can suggest a method that may work. Second, printf specifiers contain not only type information but formatting information as well. This is really only an issue with floating point types, but in that case the user may want to specify whether they want scientific notation, decimal notation, etc. Sean
Jul 02 2004
On Fri, 02 Jul 2004 18:00:09 -0700, Sean Kelly <sean f4.ca> wrote:Regan Heath wrote:I was wondering the same thing, however, do you ever need to differentiate? What are you going to print in either case, an address right? or..The new printf would not necessarily have to even use %s %S %d %l etc.. in fact why should you need to tell it what type the arguments are at all? it already knows! IMO the new printf should work something like this... int a; long b; real c; printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c); or similar, basically you specify the position of the arg to use, this allows this also: printf("regan was $1 and also $1 again",a);I see two problems with this. First, as per my post I don't know if there's any way to differentiate between a dynamic D array and a pointer to a sequence of the same type.Hopefully Walter can suggest a method that may work. Second, printf specifiers contain not only type information but formatting information as well. This is really only an issue with floating point types, but in that case the user may want to specify whether they want scientific notation, decimal notation, etc.True, e, f and g and also d, i, o and x behave differently. We could incorporate this information into the format string another way, more like the width and precision specifiers. I am struggling to come up with a nice compact way to do it... Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 03 2004
Regan Heath wrote:On Fri, 02 Jul 2004 18:00:09 -0700, Sean Kelly <sean f4.ca> wrote:How each type is handled is different. D arrays have a length specifier and are not null terminated (indeed, they may legally contain multiple nulls) while C arrays have no length specifier and are null terminated. So the routine to find the end of each type will be different. This turned out to be a problem for me with scanf. I've added %S as the D alternative to %s and %C as the D alternative to %C but that leaves me with no good solution for scansets (%[a-b]). I'm currently defaulting to D-style arrays in this case but the code will crash if a C-style array is passed.I see two problems with this. First, as per my post I don't know if there's any way to differentiate between a dynamic D array and a pointer to a sequence of the same type.I was wondering the same thing, however, do you ever need to differentiate? What are you going to print in either case, an address right? or..Possibly something like this $[1f]. The braces could enclose all needed information about type formatting. Or if consistency with scanf is desired then perhaps a different brace type: %{1f}. Still not ideal, but it's something. SeanHopefully Walter can suggest a method that may work. Second, printf specifiers contain not only type information but formatting information as well. This is really only an issue with floating point types, but in that case the user may want to specify whether they want scientific notation, decimal notation, etc.True, e, f and g and also d, i, o and x behave differently. We could incorporate this information into the format string another way, more like the width and precision specifiers. I am struggling to come up with a nice compact way to do it...
Jul 03 2004
On Sat, 03 Jul 2004 16:05:08 -0700, Sean Kelly <sean f4.ca> wrote:Regan Heath wrote:Ahh.. I see.. you were talking about the value of the array, not the reference itself. What typeinfo does it give for a D array? and what for a char *? I suspect eventually the typeinfo will be different, and you will be able to treat them as you need to. Walter has mentioned several times that TypeInfo will get better. I dont think we can write this new printf variant until the TypeInfo updates/changes are complete.On Fri, 02 Jul 2004 18:00:09 -0700, Sean Kelly <sean f4.ca> wrote:How each type is handled is different. D arrays have a length specifier and are not null terminated (indeed, they may legally contain multiple nulls) while C arrays have no length specifier and are null terminated. So the routine to find the end of each type will be different. This turned out to be a problem for me with scanf. I've added %S as the D alternative to %s and %C as the D alternative to %C but that leaves me with no good solution for scansets (%[a-b]). I'm currently defaulting to D-style arrays in this case but the code will crash if a C-style array is passed.I see two problems with this. First, as per my post I don't know if there's any way to differentiate between a dynamic D array and a pointer to a sequence of the same type.I was wondering the same thing, however, do you ever need to differentiate? What are you going to print in either case, an address right? or..See my post to Juliano, I came up with some ideas. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/Possibly something like this $[1f]. The braces could enclose all needed information about type formatting. Or if consistency with scanf is desired then perhaps a different brace type: %{1f}. Still not ideal, but it's something.Hopefully Walter can suggest a method that may work. Second, printf specifiers contain not only type information but formatting information as well. This is really only an issue with floating point types, but in that case the user may want to specify whether they want scientific notation, decimal notation, etc.True, e, f and g and also d, i, o and x behave differently. We could incorporate this information into the format string another way, more like the width and precision specifiers. I am struggling to come up with a nice compact way to do it...
Jul 03 2004
Regan Heath wrote:printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c);What if we have more than 9 arguments? "$10" is the 10th argument or the 1st argument followed by a zero? We may also need aditional information on the format codes: - number of characters to reserve (strings, integer, etc); - max number of character before trunc (strings mostly); - how to print thousands separator (localizable; integers and floats); - hex char case (0X1EF vs 0x1ef) (integers only); - how to decorate octals and hexadecimals (localizable; integers only); - precision and significant digits (floats); - full representation or scientific notation (floats). And some of the above information may also appear among the arguments (for example, if you want to dynamic calculate column sizes, the number of characters to reserve would be better placed among the arguments). -- Miles "Threat Eliminated." - Tio
Jul 03 2004
On Sat, 03 Jul 2004 14:16:49 -0300, Juliano Ravasi Ferraz <contact write-my-first-name-here.info> wrote:Regan Heath wrote:The way the original printf avoids this problem is that when it uses numbers i.e. for width/precison etc it always follows them with either a . or the type character. So in this case we'd have to use another $ char i.e. printf("$1$0 $10$"); the first is param 1 followed by a 0, the second is param 10. The other alternative is to use letters, that gives a slightly higher limit of 26, which only delays the problem.printf("my int is $1 my long is $2 and my real is $3",a,b,c); printf("my long is $2 my real is $3 and my int is $1",a,b,c);What if we have more than 9 arguments? "$10" is the 10th argument or the 1st argument followed by a zero?We may also need aditional information on the format codes: - number of characters to reserve (strings, integer, etc); - max number of character before trunc (strings mostly); - how to print thousands separator (localizable; integers and floats); - hex char case (0X1EF vs 0x1ef) (integers only); - how to decorate octals and hexadecimals (localizable; integers only); - precision and significant digits (floats); - full representation or scientific notation (floats). And some of the above information may also appear among the arguments (for example, if you want to dynamic calculate column sizes, the number of characters to reserve would be better placed among the arguments).We want to try and do these things similarly to the orginal, so dynamic sizes would use the * symbol, width and precision would remain the same.. perhaps.. printf("$5.3,1$"); width of 5, '.' to seperate, precision of 3, ',' to seperate, then param number. That leaves the differences between d, o, and x and also f, g and e which we can add as flags eg. Existing flags – + 0 blank (' ') New flags o - octal representation x/X - hex representation e - scientific (floats) g - most compact (floats) eg. printf(" $x,5.3,1$ "); - in hex printf(" $ x,5.3,1$ "); - in hex pad with spaces printf(" $0x,5.3,1$ "); - in hex pad with zeroes printf(" $#x,5.3,1$ "); - in hex prefix with 0x printf(" $0o,*.*,1$ "); - in octal prefix with zeroes, dynamic width and precision Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 03 2004
In 0.93, the code: int main() { char c; printf( "%i %i\n", char.init, c.init ); printf( "%i %i\n", char.min, c.min ); printf( "%i %i\n", char.max, c.max ); return 0; } prints: 255 255 0 0 255 255 And in 0.94 it prints: -1 255 0 0 -1 -1 I'm not sure offhand if this is a bug with properties returning signed numbers sometimes or if it's just a problem with printf. If I change the code to this: int main() { char c; printf( "%u %u\n", char.init, c.init ); printf( "%u %u\n", char.min, c.min ); printf( "%u %u\n", char.max, c.max ); return 0; } This is the output in 0.94: 4294967295 255 0 0 4294967295 4294967295 Sean
Jul 04 2004
In article <ccarcn$jsl$1 digitaldaemon.com>, Sean Kelly says...In 0.93, the code: int main() { char c; printf( "%i %i\n", char.init, c.init ); printf( "%i %i\n", char.min, c.min ); printf( "%i %i\n", char.max, c.max ); return 0; }Why are you using "%i"? What does it mean? (Maybe it needs to be added to our specifier list: http://www.prowiki.org/wiki4d/wiki.cgi?HowTo/printf) I'd think you want either "%u" for decimal or %x for hex.prints: 255 255 0 0 255 255 And in 0.94 it prints: -1 255 0 0 -1 -1 I'm not sure offhand if this is a bug with properties returning signed numbers sometimes or if it's just a problem with printf. If I change the code to this: int main() { char c; printf( "%u %u\n", char.init, c.init ); printf( "%u %u\n", char.min, c.min ); printf( "%u %u\n", char.max, c.max ); return 0; } This is the output in 0.94: 4294967295 255That's odd. I thought they'd both be 255. Well, I've never completely understood printf (and I don't think I'll be sad when if it becomes obsolete).0 0 4294967295 4294967295Again, I thought they'd both be 255.Seanjcc7
Jul 04 2004
On Mon, 5 Jul 2004 06:36:46 +0000 (UTC), J C Calvarese <jcc7 cox.net> wrote:In article <ccarcn$jsl$1 digitaldaemon.com>, Sean Kelly says...It's identical to %d. (according to MSDN) type | output format -------------------- d int | Signed decimal integer. i int | Signed decimal integer. o int | Unsigned octal integer. u int | Unsigned decimal integer. x int | Unsigned hexadecimal integer, using “abcdef.” X int | Unsigned hexadecimal integer, using “ABCDEF.” (from MSDN)In 0.93, the code: int main() { char c; printf( "%i %i\n", char.init, c.init ); printf( "%i %i\n", char.min, c.min ); printf( "%i %i\n", char.max, c.max ); return 0; }Why are you using "%i"? What does it mean? (Maybe it needs to be added to our specifier list: http://www.prowiki.org/wiki4d/wiki.cgi?HowTo/printf)I'd think you want either "%u" for decimal or %x for hex.As would I, I think however, something stranger is going on, this code: void main() { int v; v = char.init; printf("%i %i\n",char.init,v); } prints: 255 255 yet this code: void main() { int v; //v = char.init; printf("%i %i\n",char.init,v); } prints: -1 0 err.. weird.prints: 255 255 0 0 255 255 And in 0.94 it prints: -1 255 0 0 -1 -1 I'm not sure offhand if this is a bug with properties returning signed numbers sometimes or if it's just a problem with printf. If I change the code to this: int main() { char c; printf( "%u %u\n", char.init, c.init ); printf( "%u %u\n", char.min, c.min ); printf( "%u %u\n", char.max, c.max ); return 0; } This is the output in 0.94: 4294967295 255That's odd. I thought they'd both be 255.Well, I've never completely understood printf (and I don't think I'll be sad when if it becomes obsolete).printf is just so useful...Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/0 0 4294967295 4294967295Again, I thought they'd both be 255.
Jul 05 2004
In article <opsanm6fgc5a2sq9 digitalmars.com>, Regan Heath says...Right, so the only way it can ever become obsolete is if something even better comes along. So if that happens, I won't be sad either. You wouldn't exactly be losing a function - just gaining another one. JillWell, I've never completely understood printf (and I don't think I'll be sad when if it becomes obsolete).printf is just so useful...
Jul 05 2004
On Mon, 5 Jul 2004 21:04:23 +0000 (UTC), Arcane Jill <Arcane_member pathlink.com> wrote:In article <opsanm6fgc5a2sq9 digitalmars.com>, Regan Heath says...Yeah, I know.. the posts on the new printf seem promising. IMO TypeInfo deficiencies are all that are holding it back. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/Right, so the only way it can ever become obsolete is if something even better comes along. So if that happens, I won't be sad either. You wouldn't exactly be losing a function - just gaining another one.Well, I've never completely understood printf (and I don't think I'll be sad when if it becomes obsolete).printf is just so useful...
Jul 05 2004