Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 16, 2013 does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting? I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure. Thanks Dan import std.conv; struct T { int[] i; string[string] ss; } void foo(ref T t) { } void main() { T t1; auto t2 = immutable T(); foo(t1); foo(cast()t2); } |
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:
> import std.conv;
>
> struct T {
> int[] i;
> string[string] ss;
> }
>
> void foo(ref T t) {
> }
>
> void main() {
> T t1;
> auto t2 = immutable T();
> foo(t1);
> foo(cast()t2);
> }
It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote: > > It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want. How do you propose to make a mutable copy *generically*? I think a legitimate use would be the following. In the construction of S I want to use a T to construct an R. `this(...) immutable {}` prevents initialization of R in this case. Maybe immutable adorning `this()` should mean it is immutable upon the end of the construction, giving the initialization a chance to actually initialize. In the example below a better approach would be to have: R createRFromT(ref const(T) t) pure {...} but with what I'm using from phobos that is not possible. ------------------------------------------------ import std.conv; import std.stdio; struct R { int[] i; string[string] ss; } struct T { int[] i; string[string] ss; } struct S { R r; this(ref const(T) t) immutable { createRFromT(t, r); } } void createRFromT(ref const(T) t, ref R r) { //... } void main() { T t1; auto t2 = immutable T(); auto s = immutable S(t2); } |
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | struct S { R r; this(ref immutable(T) t) immutable { r.tupleof = t.tupleof; } } ? |
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:
> On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote:
>>
>> It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.
>
> How do you propose to make a mutable copy *generically*?
Recursively going through the levels of indirection via static introspection and allocating memory for new mutable counter-parts as it goes. Maybe it should belong to Phobos, no idea right now, will know once I ever find the need for it.
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:
> The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting?
>
> I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure.
>
> Thanks
> Dan
>
> import std.conv;
>
> struct T {
> int[] i;
> string[string] ss;
> }
>
> void foo(ref T t) {
> }
>
> void main() {
> T t1;
> auto t2 = immutable T();
> foo(t1);
> foo(cast()t2);
> }
foo([cast()t2][0]);
(It would be good to have compound literals like in C)
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 16 October 2013 at 17:55:56 UTC, Dicebot wrote:
> struct S {
> R r;
> this(ref immutable(T) t) immutable {
> r.tupleof = t.tupleof;
> }
> }
>
> ?
Thanks. It is cute - but not so helpful. The example stands. I *need* to call a createRFromT.
Their shapes are the same in this simple example because I simplified. Make R look like:
struct R {
string[string] ss;
int[] j;
}
and the cute trick falls apart. In words, I have an R and I want to make a T. The R is const the T will be immutable because the ctor requires it. But it is technically not immutable until it is initialized.
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wednesday, 16 October 2013 at 17:58:41 UTC, Dicebot wrote:
> On Wednesday, 16 October 2013 at 17:50:48 UTC, Daniel Davidson wrote:
>> On Wednesday, 16 October 2013 at 17:16:39 UTC, Dicebot wrote:
>>>
>>> It works as it should. Make a mutable copy of t2 and pass it. Or make foo() accept const. I can't imagine a single legitimate use case for destroying type system in a way you want.
>>
>> How do you propose to make a mutable copy *generically*?
>
> Recursively going through the levels of indirection via static introspection and allocating memory for new mutable counter-parts as it goes. Maybe it should belong to Phobos, no idea right now, will know once I ever find the need for it.
I agree with the sentiment. But as it stands I think a copy should not be necessary. I could make a local mutable R, pass it to createRFromT to get it initialized and then copy it back somehow to the member variable r. That to me is silly. The copy should not be required.
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Wednesday, 16 October 2013 at 18:09:55 UTC, Maxim Fomin wrote:
> On Wednesday, 16 October 2013 at 17:05:25 UTC, Daniel Davidson wrote:
>> The code below fails to compile due to the last line. I was hoping casting away immutable would allow the call to foo. I think it is not accepted because of the rval to ref issue. If that is the case, how can foo be called by casting?
>>
>> I'm not a fan of casting but I'm finding cases where it is the only recourse to create immutable data using impure functions that should be pure.
>>
>> Thanks
>> Dan
>>
>> import std.conv;
>>
>> struct T {
>> int[] i;
>> string[string] ss;
>> }
>>
>> void foo(ref T t) {
>> }
>>
>> void main() {
>> T t1;
>> auto t2 = immutable T();
>> foo(t1);
>> foo(cast()t2);
>> }
>
> foo([cast()t2][0]);
>
> (It would be good to have compound literals like in C)
Haaah - brilliant. Scary, but brilliant.
|
October 16, 2013 Re: does cast make an lvalue appear to be an rvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Davidson | On Wednesday, 16 October 2013 at 18:14:22 UTC, Daniel Davidson wrote:
> I agree with the sentiment. But as it stands I think a copy should not be necessary. I could make a local mutable R, pass it to createRFromT to get it initialized and then copy it back somehow to the member variable r. That to me is silly. The copy should not be required.
Then don't use immutable. Root of all problems with immutable comes from trying to use it for something it should never be. `immutable` means "never ever can be accessed with a mutable" with any compiler optimization that may come from that. Any cast is undefined behavior in a form of time bomb. Basically, only thing immutable is good at is to create some potentially shared data and slicing / reading it when needed. If you need the same data but for passing as mutable function argument, you MUST make a copy, there is no safe way around it.
|
Copyright © 1999-2021 by the D Language Foundation