Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 11, 2006 Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
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. |
February 11, 2006 Re: Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant | "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. |
February 11, 2006 Re: Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant | 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 |
February 12, 2006 Re: Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | 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, Australia
Okay, 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.
|
February 13, 2006 Re: Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> "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.
>
>
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-Sauls
|
February 15, 2006 Re: Bug in std.format.doFormat? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant | 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. |
Copyright © 1999-2021 by the D Language Foundation