Thread overview
Can we check the arguments to format() at compile time?
Apr 01, 2016
Yuxuan Shui
Apr 01, 2016
Alex Parrill
Apr 01, 2016
Yuxuan Shui
Apr 02, 2016
Jacob Carlborg
Apr 02, 2016
Daniel Murphy
Apr 02, 2016
Johan Engelen
April 01, 2016
Clang has this nice feature that it will warn you when you passed wrong arguments to printf:

#include <stdio.h>
int main(){
	long long u = 10;
	printf("%c", u);
}

clang something.c:
something.c:4:15: warning: format specifies type 'int' but the argument has type 'long long' [-Wformat]

With the CTFE power of D, we should be able to do the same thing when the format string is available at compile time. Instead of throwing exceptions at run time.
April 01, 2016
On Friday, 1 April 2016 at 21:25:46 UTC, Yuxuan Shui wrote:
> Clang has this nice feature that it will warn you when you passed wrong arguments to printf:
>
> #include <stdio.h>
> int main(){
> 	long long u = 10;
> 	printf("%c", u);
> }
>
> clang something.c:
> something.c:4:15: warning: format specifies type 'int' but the argument has type 'long long' [-Wformat]
>
> With the CTFE power of D, we should be able to do the same thing when the format string is available at compile time. Instead of throwing exceptions at run time.

Not as-is, because the format string is a runtime argument and not a compile-time constant.

Consider:

    writefln(rand() >= 0.5 ? "%s" : "%d", 123);

It's certainly possible with a new, templated writef function. Hypothetically:

    writefln_ctfe!"%s"(1234); // would fail
April 01, 2016
On Friday, 1 April 2016 at 23:26:14 UTC, Alex Parrill wrote:
> On Friday, 1 April 2016 at 21:25:46 UTC, Yuxuan Shui wrote:
>> [...]
>
> Not as-is, because the format string is a runtime argument and not a compile-time constant.
>
> Consider:
>
>     writefln(rand() >= 0.5 ? "%s" : "%d", 123);
>
> It's certainly possible with a new, templated writef function. Hypothetically:
>
>     writefln_ctfe!"%s"(1234); // would fail

That's kind of ugly. Now I really wish D can unify template arguments and function arguments known at compile time.
April 02, 2016
On 2/04/2016 8:25 AM, Yuxuan Shui wrote:
> Clang has this nice feature that it will warn you when you passed wrong
> arguments to printf:
>
> #include <stdio.h>
> int main(){
>      long long u = 10;
>      printf("%c", u);
> }
>
> clang something.c:
> something.c:4:15: warning: format specifies type 'int' but the argument
> has type 'long long' [-Wformat]
>
> With the CTFE power of D, we should be able to do the same thing when
> the format string is available at compile time. Instead of throwing
> exceptions at run time.

That's something I want to do with this eventually: https://github.com/D-Programming-Language/dmd/pull/3799

When arguments (or anything about the arguments) is known at compile time, some subsets of in-contracts can be checked.

Currently only stuff like this is supported:
auto iota(int low, int high) in { assert(low <= high); } body { ... }

iota(23, 7); // Error

But it's not impossible that
assert(checkFormatArgs(format, args));
could work one day.
April 02, 2016
On 2016-04-02 01:40, Yuxuan Shui wrote:

> That's kind of ugly. Now I really wish D can unify template arguments
> and function arguments known at compile time.

Sounds like AST macros.

-- 
/Jacob Carlborg
April 02, 2016
On Friday, 1 April 2016 at 21:25:46 UTC, Yuxuan Shui wrote:
> Clang has this nice feature that it will warn you when you passed wrong arguments to printf:
>
> #include <stdio.h>
> int main(){
> 	long long u = 10;
> 	printf("%c", u);
> }
>
> clang something.c:
> something.c:4:15: warning: format specifies type 'int' but the argument has type 'long long' [-Wformat]
>
> With the CTFE power of D, we should be able to do the same thing when the format string is available at compile time. Instead of throwing exceptions at run time.

I thought LDC already did that when `-check-printf-calls` is passed, but the implementation is unfinished and it does not do any checking at the moment.
April 02, 2016
On 04/01/2016 07:26 PM, Alex Parrill wrote:
> On Friday, 1 April 2016 at 21:25:46 UTC, Yuxuan Shui wrote:
>> Clang has this nice feature that it will warn you when you passed
>> wrong arguments to printf:
>>
>> #include <stdio.h>
>> int main(){
>>     long long u = 10;
>>     printf("%c", u);
>> }
>>
>> clang something.c:
>> something.c:4:15: warning: format specifies type 'int' but the
>> argument has type 'long long' [-Wformat]
>>
>> With the CTFE power of D, we should be able to do the same thing when
>> the format string is available at compile time. Instead of throwing
>> exceptions at run time.
>
> Not as-is, because the format string is a runtime argument and not a
> compile-time constant.
>
> Consider:
>
>      writefln(rand() >= 0.5 ? "%s" : "%d", 123);
>
> It's certainly possible with a new, templated writef function.
> Hypothetically:
>
>      writefln_ctfe!"%s"(1234); // would fail

What happened to the work that added a compile-time string to writef? -- Andrei