digitalmars.D.learn - writef, compile-checked format, pointer
- novice2 (15/15) Aug 09 2021 format!"fmt"() and writef!"fmt"() templates
- Patrick Schluter (10/25) Aug 09 2021 Yes. %X is to format integers. Runtime evaluation of a format
- Bastiaan Veelo (11/31) Aug 09 2021 It is to format pointers as well, according to the last table on
- =?UTF-8?Q?Ali_=c3=87ehreli?= (21/49) Aug 09 2021 Sensible explanation but it conflicts both with the documentation at
- Adam D Ruppe (15/18) Aug 09 2021 The compile time checker is pretty bad tbh, it just tries to ctfe
- =?UTF-8?Q?Ali_=c3=87ehreli?= (3/6) Aug 09 2021 My personal policy is to kindly ask you to fix it! :p
- nov (11/13) Aug 09 2021 i saw this message too, and this is one of reasons of my original
- Tejas (3/4) Aug 10 2021 That is why C++ introduced concepts. Wonder when D will be
- =?UTF-8?Q?Ali_=c3=87ehreli?= (8/11) Aug 10 2021 format.
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?
Aug 09 2021
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. 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);
Aug 09 2021
On Monday, 9 August 2021 at 22:01:18 UTC, Patrick Schluter wrote:On Monday, 9 August 2021 at 19:38:28 UTC, novice2 wrote:It is to format pointers as well, according to the last table on https://dlang.org/phobos/std_format.html. |Type|Format character|Formatted as| |-|-|-| |Pointer| 's' |A null pointer is formatted as 'null'. All other pointers are formatted as hexadecimal numbers with the format character 'X'.| | |'x', 'X' |Formatted as a hexadecimal number.| It looks like a bug to me. — Bastiaan.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.
Aug 09 2021
On 8/9/21 3:01 PM, Patrick Schluter wrote:On Monday, 9 August 2021 at 19:38:28 UTC, novice2 wrote: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.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.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
Aug 09 2021
On Monday, 9 August 2021 at 22:30:43 UTC, Ali Çehreli wrote:I don't know the reason but I suspect a bug in the compile-time checker that involves .init values for arguments.The compile time checker is pretty bad tbh, it just tries to ctfe execute the given string and sees if it throws. That's kinda clever; the simplest thing that can possibly work, no doubt. But since ctfe cannot work with certain things - like the pointer casts which are done here* - this makes it a bit fragile. And the implementation is really really slow and pretty bloated in codegen too. My personal policy is to never use it. * The compiler probably could special-case `null` at least since that's consistently 0 in D.Perhaps the un-typed 'null' literal is used somewhere.The line is this: const pnum = () trusted { return cast(ulong) p; }(); Which is already blargh code, but in ctfe it is a prohibited operation.
Aug 09 2021
On 8/9/21 3:46 PM, Adam D Ruppe wrote:The compile time checker [...] implementation is really really slow and pretty bloated in codegen too. My personal policy is to never use it.My personal policy is to kindly ask you to fix it! :p Ali
Aug 09 2021
On Monday, 9 August 2021 at 22:30:43 UTC, Ali Çehreli wrote:Error: expression `FormatException("Expected one of %s, %x or %X for pointer type.",i saw this message too, and this is one of reasons of my original question. '%s' bad for pointer in my cases, because result often contains something like "init" or "cast(int*)mytype" i dreamed that programming will be less-error with compile checking format. but reality disappoint :( message for every error in compile-checked format occupy whole screen :( every time i try to use templates, i have problems :(
Aug 09 2021
On Tuesday, 10 August 2021 at 05:03:12 UTC, nov wrote:every time i try to use templates, i have problems :(That is why C++ introduced concepts. Wonder when D will be getting them :(
Aug 10 2021
On 8/9/21 10:03 PM, nov wrote:i dreamed that programming will be less-error with compile checkingformat. I still think so because many errors that can be caught at compile time are moved to run time in non-statically-typed languages.but reality disappoint :( message for every error in compile-checked format occupy whole screen :(When that happens, I simply change it to runtime-checked format string like you did and it works. (Better would be to identify and fix the problem. Maybe some other time for me...) Ali
Aug 10 2021