Thread overview
How to turn an inout(Object) into a string
Apr 26, 2015
Meta
Apr 26, 2015
tcak
Apr 26, 2015
Meta
Apr 26, 2015
Jonathan M Davis
Apr 26, 2015
Meta
Apr 26, 2015
Jonathan M Davis
April 26, 2015
The following code spits out pages of error messages, and it's driving me insane. I know that Object.toString only has a mutable variant, so how am I supposed to use writeln, toString, etc. with an inout, const, or immutable object?

void main(inout string[] args)
{
	import std.stdio;
	
	immutable(Object) o = new immutable Object();
        //Compile error: template instance
        //std.format.formatGeneric!(
        //        LockingTextWriter, immutable(Object),
        //        char)
        //error instantiating
	writeln(o);
}
April 26, 2015
On Sunday, 26 April 2015 at 03:09:17 UTC, Meta wrote:
> The following code spits out pages of error messages, and it's driving me insane. I know that Object.toString only has a mutable variant, so how am I supposed to use writeln, toString, etc. with an inout, const, or immutable object?
>
> void main(inout string[] args)
> {
> 	import std.stdio;
> 	
> 	immutable(Object) o = new immutable Object();
>         //Compile error: template instance
>         //std.format.formatGeneric!(
>         //        LockingTextWriter, immutable(Object),
>         //        char)
>         //error instantiating
> 	writeln(o);
> }

writeln( cast(Object)o );

Tada!!
April 26, 2015
On Sunday, 26 April 2015 at 03:48:00 UTC, tcak wrote:
> On Sunday, 26 April 2015 at 03:09:17 UTC, Meta wrote:
>> The following code spits out pages of error messages, and it's driving me insane. I know that Object.toString only has a mutable variant, so how am I supposed to use writeln, toString, etc. with an inout, const, or immutable object?
>>
>> void main(inout string[] args)
>> {
>> 	import std.stdio;
>> 	
>> 	immutable(Object) o = new immutable Object();
>>        //Compile error: template instance
>>        //std.format.formatGeneric!(
>>        //        LockingTextWriter, immutable(Object),
>>        //        char)
>>        //error instantiating
>> 	writeln(o);
>> }
>
> writeln( cast(Object)o );
>
> Tada!!

Also undefined behaviour, AFAIK.
April 26, 2015
On Sunday, April 26, 2015 03:51:25 Meta via Digitalmars-d-learn wrote:
> On Sunday, 26 April 2015 at 03:48:00 UTC, tcak wrote:
> > On Sunday, 26 April 2015 at 03:09:17 UTC, Meta wrote:
> >> The following code spits out pages of error messages, and it's driving me insane. I know that Object.toString only has a mutable variant, so how am I supposed to use writeln, toString, etc. with an inout, const, or immutable object?
> >>
> >> void main(inout string[] args)
> >> {
> >>    import std.stdio;
> >>
> >>    immutable(Object) o = new immutable Object();
> >>        //Compile error: template instance
> >>        //std.format.formatGeneric!(
> >>        //        LockingTextWriter, immutable(Object),
> >>        //        char)
> >>        //error instantiating
> >>    writeln(o);
> >> }
> >
> > writeln( cast(Object)o );
> >
> > Tada!!
>
> Also undefined behaviour, AFAIK.

It's only undefined if mutation is involved, though I don't know if mutation is involved in this case or not (I wouldn't think so, but I don't know), and in general, you definitely shouldn't be casting away const. The real problem here is likely that toString on Object isn't const, and we can't make it const. The fix for that which was decided upon was to remove toString, toHash, opCmp, and opEquals from Object altogether, since we have proper templates in D and don't really need to put any of those on Object directly (in which case printing out a plain Object wouldn't work at all anyway), but there's a fair bit to do before those changes can be made, and unfortunately, not much of the work for it has been done yet.

https://issues.dlang.org/show_bug.cgi?id=9769 https://issues.dlang.org/show_bug.cgi?id=9770 https://issues.dlang.org/show_bug.cgi?id=9771 https://issues.dlang.org/show_bug.cgi?id=9772

- Jonathan M Davis

April 26, 2015
On Sunday, 26 April 2015 at 04:52:36 UTC, Jonathan M Davis wrote:
> It's only undefined if mutation is involved, though I don't know if mutation is involved in this case or not

I was thinking that a class can define an arbitrary toString() that modifies it some of its member variables, which definitely breaks const-correctness.

class CustomToString
{
    int n;

    override string toString()
    {
        n = 1;

        return "Uh oh";
    }
}

void main()
{
    import std.stdio;

    immutable c = new CustomToString();
    writeln(cast()c);
}

April 26, 2015
On Sunday, April 26, 2015 05:09:30 Meta via Digitalmars-d-learn wrote:
> On Sunday, 26 April 2015 at 04:52:36 UTC, Jonathan M Davis wrote:
> > It's only undefined if mutation is involved, though I don't know if mutation is involved in this case or not
>
> I was thinking that a class can define an arbitrary toString() that modifies it some of its member variables, which definitely breaks const-correctness.
>
> class CustomToString
> {
>      int n;
>
>      override string toString()
>      {
>          n = 1;
>
>          return "Uh oh";
>      }
> }
>
> void main()
> {
>      import std.stdio;
>
>      immutable c = new CustomToString();
>      writeln(cast()c);
> }

Yes. That's legal and would be one reason to not just cast away const on an Object and call toString on it. It's just that in the example given, an immutable Object was constructed directly, and Object's toString isn't going to mutate anything. The question would be whether the call to writeln would (and it shouldn't). So, in the OP's code, I don't think that it's actually a problem, but in general, it could be, so it's ill-advised to cast away const - certainly, if you're going to, you need to be sure that mutation isn't going to occur to the object from which you cast away const.

But I'd also argue that almost no code should be using Object for much of anything anyway. In theory, we're going to get rid of most of the functions on Object at some point here, at which point, Object won't be much more than a void* specific to class objects. And the implementations of those functions on Object are pretty useless anyway.

- Jonathan M Davis