digitalmars.D.bugs - Bug in std.format.doFormat?
- Deewiant (36/36) Feb 11 2006 Note how the format string doesn't change but the order of the arguments...
- Jarrett Billingsley (10/53) Feb 11 2006 This might actually be "expected" behavior, as evidenced by these lines ...
- Chris Sauls (6/79) Feb 12 2006 I would actually argue its a bug (or symptom of incomplete implementatio...
- Derek Parnell (20/22) Feb 11 2006 On Sun, 12 Feb 2006 08:12:06 +1100, Deewiant
- Deewiant (6/19) Feb 12 2006 Okay, I can see how it makes sense for strings. But what about something...
- Walter Bright (4/4) Feb 14 2006 A %s format will take any argument type, and print it as a string. This ...
Note how the format string doesn't change but the order of the arguments does: -- import std.string, std.stdio; void main() { printf("%s %d\n", toStringz("foo"), 5); // "foo 5" // printf("%s %d", 5, toStringz("foo")); // access violation writefln("%s %d", "foo", 5); // "foo 5" writefln("%s %d", 5, "foo"); // "5 foo"?? char[] s = format("%s %d", "foo", 5); writefln(s); // "foo 5" s = format("%s %d", 5, "foo"); writefln(s); // "5 foo"?? } -- Or, to clarify: When using printf(), if the arguments do not match the format string exactly, _including their order_, an access violation occurs. When using writef(), or std.string.format(), one can pass ("%s %d", 5, "foo") and get the same result as from ("%d %s", 5, "foo") or ("%s %d", "foo", 5), even though, in the former case, 5 does not match "%s" and "foo" does not match "%d". That is, the order of the arguments (or, if you prefer to think that way, the order of the types of format strings) does not matter. The ? in the title about whether this is a bug in std.format.doFormat comes from me not being sure whether the bug lies there or not, but since both the writef functions and std.string.format() use doFormat() internally (I looked at the Phobos source that much) I presume that's where the problem lies. Of course this could be a bug in the documentation: there it is said that "[m]ismatched arguments and formats result in a FormatError being thrown." Some cases in the above example certainly seem mismatched to me, yet nothing was thrown. It may be this is meant to happen (which I doubt, it just doesn't make sense), in which case the documentation needs to be corrected.
Feb 11 2006
"Deewiant" <deewiant.doesnotlike.spam gmail.com> wrote in message news:dsljv8$2r8b$1 digitaldaemon.com...Note how the format string doesn't change but the order of the arguments does: -- import std.string, std.stdio; void main() { printf("%s %d\n", toStringz("foo"), 5); // "foo 5" // printf("%s %d", 5, toStringz("foo")); // access violation writefln("%s %d", "foo", 5); // "foo 5" writefln("%s %d", 5, "foo"); // "5 foo"?? char[] s = format("%s %d", "foo", 5); writefln(s); // "foo 5" s = format("%s %d", 5, "foo"); writefln(s); // "5 foo"?? } -- Or, to clarify: When using printf(), if the arguments do not match the format string exactly, _including their order_, an access violation occurs. When using writef(), or std.string.format(), one can pass ("%s %d", 5, "foo") and get the same result as from ("%d %s", 5, "foo") or ("%s %d", "foo", 5), even though, in the former case, 5 does not match "%s" and "foo" does not match "%d". That is, the order of the arguments (or, if you prefer to think that way, the order of the types of format strings) does not matter. The ? in the title about whether this is a bug in std.format.doFormat comes from me not being sure whether the bug lies there or not, but since both the writef functions and std.string.format() use doFormat() internally (I looked at the Phobos source that much) I presume that's where the problem lies. Of course this could be a bug in the documentation: there it is said that "[m]ismatched arguments and formats result in a FormatError being thrown." Some cases in the above example certainly seem mismatched to me, yet nothing was thrown. It may be this is meant to happen (which I doubt, it just doesn't make sense), in which case the documentation needs to be corrected.This might actually be "expected" behavior, as evidenced by these lines from the unittest in std.format: s = std.string.format("hello world! %s %s ", true, 57, 1_000_000_000, 'x', " foo"); assert(s == "hello world! true 57 1000000000x foo"); ??? What a weird way to go about it. It might not technically be a bug, but it sure is confusing and counterintuitive.
Feb 11 2006
Jarrett Billingsley wrote:"Deewiant" <deewiant.doesnotlike.spam gmail.com> wrote in message news:dsljv8$2r8b$1 digitaldaemon.com...I would actually argue its a bug (or symptom of incomplete implementation?) in that the specifier given ("%d") expects an integral type (or else one representable as an integral, such as a real or a class with an opCast to integral), but it accepted a string. I would have expected a FormatException to be thrown. -- Chris Nicholson-SaulsNote how the format string doesn't change but the order of the arguments does: -- import std.string, std.stdio; void main() { printf("%s %d\n", toStringz("foo"), 5); // "foo 5" // printf("%s %d", 5, toStringz("foo")); // access violation writefln("%s %d", "foo", 5); // "foo 5" writefln("%s %d", 5, "foo"); // "5 foo"?? char[] s = format("%s %d", "foo", 5); writefln(s); // "foo 5" s = format("%s %d", 5, "foo"); writefln(s); // "5 foo"?? } -- Or, to clarify: When using printf(), if the arguments do not match the format string exactly, _including their order_, an access violation occurs. When using writef(), or std.string.format(), one can pass ("%s %d", 5, "foo") and get the same result as from ("%d %s", 5, "foo") or ("%s %d", "foo", 5), even though, in the former case, 5 does not match "%s" and "foo" does not match "%d". That is, the order of the arguments (or, if you prefer to think that way, the order of the types of format strings) does not matter. The ? in the title about whether this is a bug in std.format.doFormat comes from me not being sure whether the bug lies there or not, but since both the writef functions and std.string.format() use doFormat() internally (I looked at the Phobos source that much) I presume that's where the problem lies. Of course this could be a bug in the documentation: there it is said that "[m]ismatched arguments and formats result in a FormatError being thrown." Some cases in the above example certainly seem mismatched to me, yet nothing was thrown. It may be this is meant to happen (which I doubt, it just doesn't make sense), in which case the documentation needs to be corrected.This might actually be "expected" behavior, as evidenced by these lines from the unittest in std.format: s = std.string.format("hello world! %s %s ", true, 57, 1_000_000_000, 'x', " foo"); assert(s == "hello world! true 57 1000000000x foo"); ??? What a weird way to go about it. It might not technically be a bug, but it sure is confusing and counterintuitive.
Feb 12 2006
On Sun, 12 Feb 2006 08:12:06 +1100, Deewiant <deewiant.doesnotlike.spam gmail.com> wrote: [snip]It may be this is meant to happen (which I doubt, it just doesn't make sense), in which case the documentation needs to be corrected.There is a BIG difference between the C printf and D's Format. In D, the format codes only describe what format to output the data in, it does not use the format codes to describe what data to expect, as printf does. This is because Format is type-safe in that it knows what datatypes it has been given so all it has to do is format it according to your requests (in the format codes used). Thus ... format("%s is the number %s", 5, "five"); is perfectly ok. You have asked it to output (format) the first parameter as a string (%s) and the second parameter as a string too. In fact, as everyting comes out as a string eventually, you only really need the specialist format codes when doing non-default toString conversions, eg. %5.2f for floating point numbers, or %06d to give you a six-character, left-zeroed integer format, etc... -- Derek Parnell Melbourne, Australia
Feb 11 2006
Derek Parnell wrote:Thus ... format("%s is the number %s", 5, "five"); is perfectly ok. You have asked it to output (format) the first parameter as a string (%s) and the second parameter as a string too. In fact, as everyting comes out as a string eventually, you only really need the specialist format codes when doing non-default toString conversions, eg. %5.2f for floating point numbers, or %06d to give you a six-character, left-zeroed integer format, etc... --Derek Parnell Melbourne, AustraliaOkay, I can see how it makes sense for strings. But what about something like this: writefln("\"%6d\" is the floating point number \"%3.2f\"", "hello", "hello"); Which spits out '" hello" is the floating point number " he"'. Formatting a string according to how many digits should be after its decimal point seems confusing, to say the least.
Feb 12 2006
A %s format will take any argument type, and print it as a string. This is so that one can do formats without needing to know the type of the argument. %d means format it as a decimal string. A string argument shouldn't print as a decimal, so format() should throw a FormatError exception on this one.
Feb 14 2006