| |
| Posted by Ali Çehreli in reply to Patrick Schluter | PermalinkReply |
|
Ali Çehreli
Posted in reply to Patrick Schluter
| On 8/9/21 3:01 PM, Patrick Schluter wrote:
> On Monday, 9 August 2021 at 19:38:28 UTC, novice2 wrote:
>> format!"fmt"() and writef!"fmt"() templates
>> with compile-time checked format string
>> not accept %X for pointers,
>>
>> but format() and writef() accept it
>>
>> https://run.dlang.io/is/aQ05Ux
>> ```
>> void main() {
>> import std.stdio: writefln;
>> int x;
>> writefln("%X", &x); //ok
>> writefln!"%s"(&x); //ok
>> //writefln!"%X"(&x); //compile error
>> }
>> ```
>>
>> is this intentional?
>
> Yes. %X is to format integers. Runtime evaluation of a format string
> does not allow for type checking. When using the template, the
> evaluation can be thorough and the types can be checked properly.
Sensible explanation but it conflicts both with the documentation at
https://dlang.org/phobos/std_format.html
and the error message for the following:
// Intentionally wrong specifier:
writefln!"%_"((int*).init);
Error: expression `FormatException("Expected one of %s, %x or %X for pointer type.", "/usr/include/dmd/phobos/std/format/internal/write.d", 2990LU, null, null, 0u)` is not constant
Both the documentation and the error message suggest %x and %X.
> You
> have 2 solutions for your problem, either a type cast
>
> writefln!"%X"(cast(size_t)&x);
>
> or using the generic format specifier that will deduce itself the format
> to using depending in the passed type.
>
> writefln!"%s"(&x);
That would be my choice but I've just learned that %s prints the null value as "null" instead of hex 0, which may be undesirable in some cases.
I think there really is a bug here.
I've been hitting a similar bug with some complex range expressions where compile-time checked format strings would not work. I don't know the reason but I suspect a bug in the compile-time checker that involves .init values for arguments. I assume the checker uses .init values to see whether the format expression compiles and works. In fact, the mention of 'null' in the OP's error message makes me think it may be related. Perhaps the un-typed 'null' literal is used somewhere. (?)
Ali
|