std.format and uninitialized elements in CTFE
berni44
dlang at d-ecke.de
Sun Dec 8 19:41:48 UTC 2019
On Sunday, 8 December 2019 at 18:16:29 UTC, Steven Schveighoffer
wrote:
>> Ali's example shows, that this is a serious issue. IMHO my
>> example should print `Foo(void)` or `Foo([void, void, void])`
>> with `int[3]`. With that, Ali's example will work.
>
> Ali's example is different, because it's given an *actually
> initialized* structure, not one that is uninitialized, and the
> compiler complains. I'd consider that an actual bug (in Phobos
> I would guess, not the compiler).
Well actually format uses only the *type* S of the second
parameter and uses S.init to check if that can be printed (if it
would use the real parameter, that could have unwanted side
effects I guess). It cannot print it, because S.init contains an
uninitialized member. This produces the error "cannot read
uninitialized variable i in CTFE". So, at that time, the code is
somehow able to recognize, that the variable "i" is
uninitialized, else it could not produce this error. What I'm
looking for is a way, to catch that. That would solve the issue.
> You are thinking incorrectly about CTFE ;) It's executing an
> *already compiled* function, at compile time.
That's indeed something, I did not know. :-)
> It's hard to have discussions about abstract types that
> obviously are not useful. Maybe if you have a more likely
> example, you can get help finding the right course of action.
As I wrote above, I was looking into issue 19769. This is the
test given there:
```
import std.uni;
import std.format;
static immutable x = format("%s",
cast(const)"test".asCapitalized);
```
This doesn't compile, because asCapitalized returns a struct
(ToCapitalizerImpl), which contains uninitialized data (dchar[3]
buf = void;) and format tries to print that. It first tries to
print it as a range, but isInputRange misses somehow, that this
struct is a range (probably because of the cast(const), but I
don't know exactly) and therefore formatValueImpl tries to print
the members of that struct directly, but as buf is not
initialized, that fails. And the result is a strange error
message (about uninitialized variables, where everything looks
initialized).
This bug could be fixed by making isInputRange recognize the
struct as a range. But while I looked, what happens, I found out,
that printing structs with uninitialized data fails (but with an
errormessage, that says, that this data is uninitialized). I
thought, it would be nice, if format would just print <void>
instead of throwing an error and hence my question if doing so is
possible.
More information about the Digitalmars-d
mailing list