digitalmars.D.learn - Why do I get this error when casting to an immutable or shared byRef
- Gary Willoughby (21/21) Jun 19 2016 In the following code, the `foo` function doesn't work when
- Gary Willoughby (21/22) Jun 19 2016 A more correct example:
- Mike Parker (10/13) Jun 19 2016 In the second example, the problem is this:
- ag0aep6g (9/31) Jun 19 2016 At the core, int* doesn't implicitly convert to immutable(int)*.
In the following code, the `foo` function doesn't work when casting to an immutable or shared type. Can anyone please explain what is happening here? Is there any way of returning such variables byRef from a malloc'd chunk of memory? import core.stdc.stdlib; ref T foo(T)() { int* foo = cast(int*) malloc(int.sizeof * 8); return *foo; } void main(string[] args) { // Works! auto bar = foo!(int)(); // Works! auto bar = foo!(const(int))(); // Error: cast(immutable(int))*foo is not an lvalue auto bar = foo!(immutable(int))(); // Error: cast(shared(int))*foo is not an lvalue auto bar = foo!(shared(int))(); }
Jun 19 2016
On Sunday, 19 June 2016 at 10:35:59 UTC, Gary Willoughby wrote:...A more correct example: import core.stdc.stdlib; import std.traits; ref T foo(T)() { alias Type = Unqual!(T); Type* foo = cast(Type*) malloc(Type.sizeof * 8); return *foo; } void main(string[] args) { // Works! auto bar = foo!(int)(); // Works! auto bar = foo!(const(int))(); // Error: cast(immutable(int))*foo is not an lvalue auto bar = foo!(immutable(int))(); // Error: cast(shared(int))*foo is not an lvalue auto bar = foo!(shared(int))(); }
Jun 19 2016
On Sunday, 19 June 2016 at 10:45:25 UTC, Gary Willoughby wrote:On Sunday, 19 June 2016 at 10:35:59 UTC, Gary Willoughby wrote:In the second example, the problem is this: alias Type = Unqual!(T); You are declaring the function to return T, which in your example is either int, const(int), immutable(int), or shared(int), but are returning a plain int in every case. This is fine for const(int), since non-const can implicitly convert to const. That is not the case for immutable(int) or shared(int). If you take out the alias to Unqual!T and replace both remaining instances of Type with T, then it works....A more correct example:
Jun 19 2016
On 06/19/2016 12:45 PM, Gary Willoughby wrote:On Sunday, 19 June 2016 at 10:35:59 UTC, Gary Willoughby wrote:At the core, int* doesn't implicitly convert to immutable(int)*. Equally, a mutable int doesn't implicitly convert to an immutable one with the same address. That conversion makes a copy, so the result is an rvalue and you can't take it's address. A mutable int does implicitly convert to a const one with the same address, because const is fine with the value changing through the mutable view. immutable would not be fine with that, so it's rejected. Same with shared, of course....A more correct example: import core.stdc.stdlib; import std.traits; ref T foo(T)() { alias Type = Unqual!(T); Type* foo = cast(Type*) malloc(Type.sizeof * 8); return *foo; } void main(string[] args) { // Works! auto bar = foo!(int)(); // Works! auto bar = foo!(const(int))(); // Error: cast(immutable(int))*foo is not an lvalue auto bar = foo!(immutable(int))(); // Error: cast(shared(int))*foo is not an lvalue auto bar = foo!(shared(int))(); }
Jun 19 2016