www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Should writef try to statically check for format specifiers?

reply Andrej Mitrovic <none none.none> writes:
There is a bug here:

import std.stdio;

void main()
{
    int index;
    writef("The index is", index);  
}

Actually I found this bug in some example code:
http://d.puremagic.com/issues/show_bug.cgi?id=5836

writef is missing a format specifier. But it still accepts this code.

Is it possible for writef to statically check whether there's a format
specifier, assuming there's multiple arguments and the first argument is a
string literal?

I realize runtime checks would be out of the question, but I'm looking for
compile-time checks when it's possible to do so.
Apr 11 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 I realize runtime checks would be out of the question, but I'm looking for
compile-time checks when it's possible to do so.

GCC is often able to catch such bugs, but Walter has recently closed my enhancement request about this :-( http://d.puremagic.com/issues/show_bug.cgi?id=4458 So a solution is to build a fwrite/fwriteln that uses a compile-time string for formatting, that performs compile-time tests using the more efficient CTFE of DMD 2.053: int foo, bar; fwriteln!"%d %s"(foo, bar); // compile-time error: bar isn't a string! Bye, bearophile
Apr 11 2011
next sibling parent Jesse Phillips <jessekphillips+D gmail.com> writes:
Andrej Mitrovic Wrote:

 %s doesn't stand for string in D.

Yes it does.
 My issue is that the arguments don't get printed out due to missing
 specifiers. That is clearly a bug. But maybe it's not a huge bug since
 it's just printing that is involved.

I think it should do what it use to do which print the extra data at the end, or it should throw an exception.
Apr 11 2011
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
bearophile Wrote:

 So a solution is to build a fwrite/fwriteln that uses a compile-time string
for formatting, that performs compile-time tests using the more efficient CTFE
of DMD 2.053:
 
 int foo, bar;
 fwriteln!"%d %s"(foo, bar); // compile-time error: bar isn't a string!

Two complaints: fprintf? A leading f is for file. %s means format as a string not the type is a string.
 Bye,
 bearophile

Apr 11 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Jesse Phillips:

 Two complaints:
 
 fprintf? A leading f is for file.
 %s means format as a string not the type is a string.

Sorry, you are right, I am silly. Bye, bearophile
Apr 11 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/12/11, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 Andrej Mitrovic Wrote:

 %s doesn't stand for string in D.

Yes it does.

I was quoting bearophile's "it should error" post, you know that.
Apr 11 2011
prev sibling next sibling parent Jesse Phillips <jessekphillips+d gmail.com> writes:
On Tue, 12 Apr 2011 01:55:24 +0200, Andrej Mitrovic wrote:

 On 4/12/11, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 Andrej Mitrovic Wrote:

 %s doesn't stand for string in D.

Yes it does.

I was quoting bearophile's "it should error" post, you know that.

I do now. Though it still stands for string ;)
Apr 11 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/12/11, Jesse Phillips <jessekphillips+d gmail.com> wrote:
 On Tue, 12 Apr 2011 01:55:24 +0200, Andrej Mitrovic wrote:

 On 4/12/11, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 Andrej Mitrovic Wrote:

 %s doesn't stand for string in D.

Yes it does.

I was quoting bearophile's "it should error" post, you know that.

I do now. Though it still stands for string ;)

It still kicks printf's butt for not having to worry about writing all the right specifiers. Just put in %s and life's easy. :)
Apr 11 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
%s doesn't stand for string in D.

My issue is that the arguments don't get printed out due to missing
specifiers. That is clearly a bug. But maybe it's not a huge bug since
it's just printing that is involved.
Apr 11 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 Apr 2011 16:35:39 -0400, Andrej Mitrovic <none none.none> wrote:

 There is a bug here:

 import std.stdio;

 void main()
 {
     int index;
     writef("The index is", index);
 }

 Actually I found this bug in some example code:  
 http://d.puremagic.com/issues/show_bug.cgi?id=5836

 writef is missing a format specifier. But it still accepts this code.

 Is it possible for writef to statically check whether there's a format  
 specifier, assuming there's multiple arguments and the first argument is  
 a string literal?

 I realize runtime checks would be out of the question, but I'm looking  
 for compile-time checks when it's possible to do so.

Why would runtime checks be out of the question? You are already parsing the string at runtime, why can't it say "hey, I processed the whole format string, but I have these arguments left over"? Would be a simple if statement... A compile-time check would be nice, but you'd have to pass it as a compile-time argument (i.e. a template parameter), which would be not-so-nice. What would be nice is if the compiler could check when you give it a string literal, and resort to runtime checks when it was a variable. I don't think that's possible, however. -Steve
Apr 12 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 I thought templated functions can be called without a bang if an
 argument can be deduced to be available at compile time. I know I've
 read about this somewhere, either TDPL or the docs. So I thought that
 writef checks the string literal at compile time, not runtime.

I think there is some confusion here. Each function call is done fully at compile time or fully at run time, there is no partial compilation. Template arguments always require the bang, and they are always taken at compile-time. Template functions may not require a bang+types if argument types can be inferred from the given arguments. Bye, bearophile
Apr 12 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/12/11, bearophile <bearophileHUGS lycos.com> wrote:
 Template functions may not require a bang+types if argument
 types can be inferred from the given arguments.

So isn't the string literal a candidate in this case?
Apr 12 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I thought templated functions can be called without a bang if an
argument can be deduced to be available at compile time. I know I've
read about this somewhere, either TDPL or the docs. So I thought that
writef checks the string literal at compile time, not runtime.

Template shenanigans..
Apr 12 2011
prev sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 11/04/11 9:35 PM, Andrej Mitrovic wrote:
 I realize runtime checks would be out of the question...

debug doRuntimeCheck(); :-)
Apr 26 2011