Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
April 09, 2012 Issue with const | ||||
---|---|---|---|---|
| ||||
Say I have type and a function look like this:
class Foo
{
void* data;
Foo clone ()
{
auto c = new Foo;
c.data = data;
return c;
}
}
void bar (Foo foo)
{
auto c = foo.clone();
...
}
Since I'm not changing anything on "foo" I thought that it could be a good idea to declare it as const.
void bar (const Foo foo)
{
auto c = foo.clone();
...
}
In this case I also have to make "clone" const as well. Which is fine sine "clone" doesn't change any of the fields.
class Foo
{
void* data;
Foo clone () const
{
auto c = new Foo;
c.data = data;
return c;
}
}
But now when I compile this code I get this error:
Error: cannot implicitly convert expression (this.data) of type const(void*) to void*
Any idea how to solve this? Or would I need to drop const.
--
/Jacob Carlborg
|
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 04/09/2012 04:49 PM, Jacob Carlborg wrote:
>
> But now when I compile this code I get this error:
>
> Error: cannot implicitly convert expression (this.data) of type
> const(void*) to void*
>
> Any idea how to solve this? Or would I need to drop const.
>
> --
> /Jacob Carlborg
Either clone the data too or use inout.
|
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2012-04-09 16:52, Timon Gehr wrote: > On 04/09/2012 04:49 PM, Jacob Carlborg wrote: >> >> But now when I compile this code I get this error: >> >> Error: cannot implicitly convert expression (this.data) of type >> const(void*) to void* >> >> Any idea how to solve this? Or would I need to drop const. >> >> -- >> /Jacob Carlborg > > Either clone the data too or use inout. Where would I use inout, on "clone"? -- /Jacob Carlborg |
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Mon, 09 Apr 2012 11:22:54 -0400, Jacob Carlborg <doob@me.com> wrote:
> On 2012-04-09 16:52, Timon Gehr wrote:
>> On 04/09/2012 04:49 PM, Jacob Carlborg wrote:
>>>
>>> But now when I compile this code I get this error:
>>>
>>> Error: cannot implicitly convert expression (this.data) of type
>>> const(void*) to void*
>>>
>>> Any idea how to solve this? Or would I need to drop const.
>>>
>>> --
>>> /Jacob Carlborg
>>
>> Either clone the data too or use inout.
>
> Where would I use inout, on "clone"?
>
// untested
inout(Foo) clone() inout {
return new inout(Foo)(data);
}
Note, you can't post-assign data, since inout is effectively const inside an inout function.
-Steve
|
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2012-04-09 17:30, Steven Schveighoffer wrote: > // untested > inout(Foo) clone() inout { > return new inout(Foo)(data); > } > > Note, you can't post-assign data, since inout is effectively const > inside an inout function. > > -Steve Ok, that works. But then I want to modify the clone: void bar (const Foo foo) { auto c = foo.clone(); c.data = ... } But now "c" is const. I don't want "c" to be const, I just want "foo" to be const. -- /Jacob Carlborg |
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Mon, 09 Apr 2012 13:51:17 -0400, Jacob Carlborg <doob@me.com> wrote:
> On 2012-04-09 17:30, Steven Schveighoffer wrote:
>
>> // untested
>> inout(Foo) clone() inout {
>> return new inout(Foo)(data);
>> }
>>
>> Note, you can't post-assign data, since inout is effectively const
>> inside an inout function.
>>
>> -Steve
>
> Ok, that works. But then I want to modify the clone:
>
> void bar (const Foo foo)
> {
> auto c = foo.clone();
> c.data = ...
> }
>
> But now "c" is const. I don't want "c" to be const, I just want "foo" to be const.
Then c.data cannot be the same reference as foo.data.
Counter-case:
void bar( const Foo foo)
{
auto c = foo.clone(); // assume this works;
*(cast(int*)c.data) = 6; // note even though I'm casting, there is no removal of const, so this should be defined behavior.
}
immutable int i = 5;
const foo = new Foo(&i);
bar(foo);
assert(i == 5); // oops, it's 6!
In that case, you have to clone the data as well.
-Steve
|
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Monday, April 09, 2012 19:51:17 Jacob Carlborg wrote:
> On 2012-04-09 17:30, Steven Schveighoffer wrote:
> > // untested
> > inout(Foo) clone() inout {
> > return new inout(Foo)(data);
> > }
> >
> > Note, you can't post-assign data, since inout is effectively const inside an inout function.
> >
> > -Steve
>
> Ok, that works. But then I want to modify the clone:
>
> void bar (const Foo foo)
> {
> auto c = foo.clone();
> c.data = ...
> }
>
> But now "c" is const. I don't want "c" to be const, I just want "foo" to be const.
I don't see how that's possible with a void* member variable. clone can be const as long as you actually deep copy all of foo's member variables. If there are any that you don't deep copy, then the fact that clone is const forces the return value to be const because of transivity. And with a void* member variable, I don't see how you could deep copy it, so the void* member variable is stuck as const, making the return value stuck as const.
- Jonathan M Davis
|
April 09, 2012 Re: Issue with const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2012-04-09 19:56, Steven Schveighoffer wrote: > Then c.data cannot be the same reference as foo.data. > > Counter-case: > > void bar( const Foo foo) > { > auto c = foo.clone(); // assume this works; > *(cast(int*)c.data) = 6; // note even though I'm casting, there is no > removal of const, so this should be defined behavior. > } > > immutable int i = 5; > const foo = new Foo(&i); > bar(foo); > > assert(i == 5); // oops, it's 6! > > In that case, you have to clone the data as well. > > -Steve Ok, I see, thanks. -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation