Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 22, 2011 Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Why doesn't this code work? struct Bar { int* x; } void foo(Bar a) {} void main() { const a = Bar(); foo(a); } But replacing int* with some other type works fine? Even if a write a postblit function for Bar, it still fails to compile. |
January 22, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Eskapp | Sean Eskapp:
> Why doesn't this code work?
This works, the Bar instance you give to foo is const.
void foo(const Bar a) {}
Bye,
bearophile
|
January 22, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Eskapp | == Quote from Sean Eskapp (eatingstaples@gmail.com)'s article
> Why doesn't this code work?
> struct Bar
> {
> int* x;
> }
> void foo(Bar a) {}
> void main()
> {
> const a = Bar();
> foo(a);
> }
> But replacing int* with some other type works fine? Even if a write a postblit
> function for Bar, it still fails to compile.
Nevermind, I realized it's because constness is transitive in pointers. A const struct with a pointer member has a const pointer member, and those can't be implicitly cast to non-const pointer members.
|
January 22, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Eskapp | Sean Eskapp:
> Nevermind, I realized it's because constness is transitive in pointers. A const struct with a pointer member has a const pointer member, and those can't be implicitly cast to non-const pointer members.
Uhm, the struct having a pointer is not important. In theory this too can't compile:
struct Bar {}
void foo(Bar b) {}
void main() {
const b = Bar();
foo(b);
}
Is this another compiler bug?
Bye,
bearophile
|
January 22, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | == Quote from bearophile (bearophileHUGS@lycos.com)'s article
> Sean Eskapp:
> > Nevermind, I realized it's because constness is transitive in pointers. A const struct with a pointer member has a const pointer member, and those can't be implicitly cast to non-const pointer members.
> Uhm, the struct having a pointer is not important. In theory this too can't compile:
> struct Bar {}
> void foo(Bar b) {}
> void main() {
> const b = Bar();
> foo(b);
> }
> Is this another compiler bug?
> Bye,
> bearophile
No, that compiles fine. Because the struct owns a pointer, the const struct owns a const pointer. When copying a const-struct to a non-const struct, this means you must cast a const-pointer to a non-const pointer, which shouldn't be allowed.
|
January 22, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > Is this another compiler bug?
The situation is nice:
struct Foo1 {}
struct Foo2 { int x; }
const struct Foo3 { int* p; }
struct Foo4 { int* p; }
void bar1(Foo1 f) {}
void bar2(Foo2 f) {}
void bar3(Foo3 f) {}
void bar4(Foo4 f) {}
void main() {
const f1 = Foo1();
bar1(f1); // no error
const f2 = Foo2();
bar2(f2); // no error
const f3 = Foo3();
bar3(f3); // no error
const f4 = Foo4();
bar4(f4); // error
}
Bye,
bearophile
|
January 23, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 23.01.2011 2:02, bearophile wrote: >> Is this another compiler bug? > The situation is nice: > > struct Foo1 {} > struct Foo2 { int x; } > const struct Foo3 { int* p; } > struct Foo4 { int* p; } > void bar1(Foo1 f) {} > void bar2(Foo2 f) {} > void bar3(Foo3 f) {} > void bar4(Foo4 f) {} > void main() { > const f1 = Foo1(); > bar1(f1); // no error > const f2 = Foo2(); > bar2(f2); // no error > const f3 = Foo3(); > bar3(f3); // no error > const f4 = Foo4(); > bar4(f4); // error > } > > Bye, > bearophile The first two are actually OK, since you pass a copy of a value type FooX to barX. If signature was void bar(ref FooX) then it should have failed. But the third makes me wonder what the *** is going on. -- Dmitry Olshansky |
January 23, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | Dmitry Olshansky: > The first two are actually OK, since you pass a copy of a value type > FooX to barX. > If signature was void bar(ref FooX) then it should have failed. > But the third makes me wonder what the *** is going on. I have added the third case to this bug report of mine: http://d.puremagic.com/issues/show_bug.cgi?id=3934 Bye, bearophile |
January 23, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | Am 23.01.2011 11:00, schrieb Dmitry Olshansky:
> On 23.01.2011 2:02, bearophile wrote:
>>> Is this another compiler bug?
>> The situation is nice:
>>
>> struct Foo1 {}
>> struct Foo2 { int x; }
>> const struct Foo3 { int* p; }
>> struct Foo4 { int* p; }
>> void bar1(Foo1 f) {}
>> void bar2(Foo2 f) {}
>> void bar3(Foo3 f) {}
>> void bar4(Foo4 f) {}
>> void main() {
>> const f1 = Foo1();
>> bar1(f1); // no error
>> const f2 = Foo2();
>> bar2(f2); // no error
>> const f3 = Foo3();
>> bar3(f3); // no error
>> const f4 = Foo4();
>> bar4(f4); // error
>> }
>>
>> Bye,
>> bearophile
>
> The first two are actually OK, since you pass a copy of a value type
> FooX to barX.
> If signature was void bar(ref FooX) then it should have failed.
> But the third makes me wonder what the *** is going on.
>
I think it's absolutely correct. Look: Foo3 is declared as const struct meaning all it's members are const. We are passing a struct like that to bar3:
const Foo3 { const int* p}
which is implicitely converted to:
Foo3 { const int* p } //not ref !!
Because it's not ref you can't manipulate the original struct anyways and the pointer is still const. As long as you don't cast you cannot change what the pointer points to so this implicit conversion is correct IMO.
It's like const(T[]) => const(T)[] .
Mafi
|
January 23, 2011 Re: Structs with pointers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mafi | On 23.01.2011 19:05, Mafi wrote: > Am 23.01.2011 11:00, schrieb Dmitry Olshansky: >> On 23.01.2011 2:02, bearophile wrote: >>>> Is this another compiler bug? >>> The situation is nice: >>> >>> struct Foo1 {} >>> struct Foo2 { int x; } >>> const struct Foo3 { int* p; } >>> struct Foo4 { int* p; } >>> void bar1(Foo1 f) {} >>> void bar2(Foo2 f) {} >>> void bar3(Foo3 f) {} >>> void bar4(Foo4 f) {} >>> void main() { >>> const f1 = Foo1(); >>> bar1(f1); // no error >>> const f2 = Foo2(); >>> bar2(f2); // no error >>> const f3 = Foo3(); >>> bar3(f3); // no error >>> const f4 = Foo4(); >>> bar4(f4); // error >>> } >>> >>> Bye, >>> bearophile >> >> The first two are actually OK, since you pass a copy of a value type >> FooX to barX. >> If signature was void bar(ref FooX) then it should have failed. >> But the third makes me wonder what the *** is going on. >> > > I think it's absolutely correct. Look: Foo3 is declared as const struct meaning all it's members are const. We are passing a struct like that to bar3: > const Foo3 { const int* p} > which is implicitely converted to: > Foo3 { const int* p } //not ref !! > Because it's not ref you can't manipulate the original struct anyways and the pointer is still const. As long as you don't cast you cannot change what the pointer points to so this implicit conversion is correct IMO. > It's like const(T[]) => const(T)[] . Right, that makes sense. But do we really need this syntax: const struct { ... } ? > > Mafi -- Dmitry Olshansky |
Copyright © 1999-2021 by the D Language Foundation