Thread overview
[Issue 4927] New: writefln silently ignores arguments not present in the format string
Sep 10, 2011
Kenji Hara
Jun 30, 2013
Andrej Mitrovic
September 23, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4927

           Summary: writefln silently ignores arguments not present in the
                    format string
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Keywords: accepts-invalid
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2010-09-23 15:33:40 PDT ---
With dmd 2.049 this program:


import std.stdio: writefln;
void main() {
    writefln("%d", 1, 2);
}


Prints:
1


But in this case I expect a compile-time error (or equivalent run-time error if the compiler is lazy and doesn't perform such very basic tests at compile-time), because the format string doesn't contain the same things as the given arguments.

In this case printing 12 is not good, because when a writefln is used, it's better to avoid possible bugs to enforce that arguments and format string match exactly.

See also bug 4458

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 24, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4927


Andrei Alexandrescu <andrei@metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |andrei@metalanguage.com
         AssignedTo|nobody@puremagic.com        |andrei@metalanguage.com


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 10, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4927



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2011-09-10 08:35:19 PDT ---
That is a design of formattedWrite. Andrei talked:

https://github.com/D-Programming-Language/phobos/pull/231#issuecomment-1995490

> Phobos used to make a fuss about ignored arguments, but I changed that. This is because it's often good to present several arguments and let the user choose the formatting string (which may ignore some argument). This is most obvious with positional parameters. The std.log implementation needs something like that.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 10, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4927



--- Comment #2 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-09-10 09:28:47 PDT ---
One possibility would be to silently ignore arguments is positional parameters are used, and not ignore them otherwise.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 10, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4927



--- Comment #3 from bearophile_hugs@eml.cc 2011-09-10 10:50:28 PDT ---
If a programmer wants to format just the first argument, then this is the code to write:

writef("%d", 1);
writefln(2);

Introducing/keeping a muddy semantics to avoid writing one more function call like is not a so good design.

Keeping designs semantically clean is usually better, because it helps avoid bugs and more importantly it avoids unexpected corner cases and unwanted side interactions.

The introduction of a special case with muddy semantics is sometimes acceptable, when it gives _significant_ advantages, that means it makes something else significantly more handy or significantly simpler, etc. But in this case I think it makes code only a bit more handy, while increasing the probability of bugs.

----------------

(In reply to comment #2)

> One possibility would be to silently ignore arguments is positional parameters are used, and not ignore them otherwise.

This is better than the current situation.


> it's often good to present several arguments and let the user choose the formatting string (which may ignore some argument).

Usually explicit is better than implicit. If this is the desired behaviour, then the right thing is to use/introduce an explicit syntax to do it. Positional arguments are meant to do this, I presume.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4927



--- Comment #4 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-06-29 20:05:49 PDT ---
*** Issue 10489 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4927



--- Comment #5 from bearophile_hugs@eml.cc 2013-06-29 20:33:16 PDT ---
(In reply to comment #4)
> *** Issue 10489 has been marked as a duplicate of this issue. ***

The body of Issue 10489:

In DMD 2.064alpha this program compiles and runs with no errors, warnings or run-time exceptions:

import std.stdio;
void main() {
    writefln("%d %d", 1, 2, 3);
}



While this gives a run-time exception:

import std.string;
void main() {
    format("%d %d", 1, 2, 3);
}


std.format.FormatException@...\dmd2\src\phobos\std\string.d(2346): Orphan format arguments: args[2..3]


To catch some programmer mistakes I suggest to turn this into an exception/error:

writefln("%d %d", 1, 2, 3);


But as stated by Andrei Alexandrescu: http://forum.dlang.org/post/kqgna8$1ese$1@digitalmars.com

> The only point I'd negotiate would be to not throw with positional arguments, and throw with sequential arguments. All code that cares uses positional specifiers anyway.

So according to Andrei this should be accepted:


import std.stdio;
void main() {
    writefln("%2$s %1$s", 1, 2, 3);
}


Currently this is accepted (and it prints "A B10"), but I think it should be
not accepted:

import std.stdio;
void main() {
    writefln("A%2$s B%1$s", 10);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------