www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - nogc inconsistent for array comparison depending on mutability of

reply rcorre <ryan rcorre.net> writes:
 nogc unittest {
     int[2] a = [1, 2];
     assert(a == [1, 2]); // OK

     immutable(int)[2] b = [1, 2];
     assert(b == [1, 2]); // fail: array literal may cause 
allocation
}

Is there any logic behind allowing the comparison with `a` but 
not `b`, or is this a compiler bug?
Apr 07 2016
parent reply Xinok <xinok live.com> writes:
On Friday, 8 April 2016 at 01:36:18 UTC, rcorre wrote:
  nogc unittest {
     int[2] a = [1, 2];
     assert(a == [1, 2]); // OK

     immutable(int)[2] b = [1, 2];
     assert(b == [1, 2]); // fail: array literal may cause 
 allocation
 }

 Is there any logic behind allowing the comparison with `a` but 
 not `b`, or is this a compiler bug?
Semantically, array literals are always allocated on the heap. In this case, the optimizer can obviously place the array on the stack or even make it static/global. However, it would be in poor design to rely on the optimizer to satisfy nogc. It comes down to portability; if the code compiles successfully with one compiler, then it should compile successfully in any other compiler. Also, the way that compilers are typically built is that semantic analysis is done in the frontend and optimization is done in the backend. Trying to build a bridge between these two would be incredibly difficult and make implementing the compiler much more complex with little gain.
Apr 07 2016
parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On Friday, 8 April 2016 at 03:14:40 UTC, Xinok wrote:
 On Friday, 8 April 2016 at 01:36:18 UTC, rcorre wrote:
  nogc unittest {
     int[2] a = [1, 2];
     assert(a == [1, 2]); // OK

     immutable(int)[2] b = [1, 2];
     assert(b == [1, 2]); // fail: array literal may cause 
 allocation
 }

 Is there any logic behind allowing the comparison with `a` but 
 not `b`, or is this a compiler bug?
Semantically, array literals are always allocated on the heap. In this case, the optimizer can obviously place the array on the stack or even make it static/global.
So nogc is enforced by the optimizer? If the comparison with b shouldn't be allowed, I suggest we add opEquals to std.range.only. This removes a need to import std.algorithm.equal and reduces bracket nesting: assert(b == only(1, 2));
Apr 08 2016
next sibling parent reply Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote:
 If the comparison with b shouldn't be allowed, I suggest we add 
 opEquals to std.range.only. This removes a need to import 
 std.algorithm.equal and reduces bracket nesting:

 assert(b == only(1, 2));
equal[1] can compare ranges of different types. It's a bit less clear than the original code though. b.equal(only(1, 2)); [1] http://dlang.org/phobos/std_algorithm_comparison.html#.equal
Apr 08 2016
parent Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On Friday, 8 April 2016 at 10:11:43 UTC, Rene Zwanenburg wrote:
 On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote:
 If the comparison with b shouldn't be allowed, I suggest we 
 add opEquals to std.range.only. This removes a need to import 
 std.algorithm.equal and reduces bracket nesting:

 assert(b == only(1, 2));
equal[1] can compare ranges of different types.
opEquals would too. Not sure what you're saying. It wouldn't replace equal, only equal(only()). Pun intended.
 It's a bit less clear than the original code though.

 b.equal(only(1, 2));
I'd argue the opposite.
 [1] http://dlang.org/phobos/std_algorithm_comparison.html#.equal
Apr 08 2016
prev sibling parent reply Dicebot <public dicebot.lv> writes:
On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote:
 Semantically, array literals are always allocated on the heap. 
 In this case, the optimizer can obviously place the array on 
 the stack or even make it static/global.
So nogc is enforced by the optimizer?
Yes, sadly. To make it sane one would need to make a list of all optimization DMD makes in that regard and put them into spec as mandatory for all compilers.
Apr 08 2016
parent reply Xinok <xinok live.com> writes:
On Friday, 8 April 2016 at 10:15:10 UTC, Dicebot wrote:
 On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote:
 Semantically, array literals are always allocated on the 
 heap. In this case, the optimizer can obviously place the 
 array on the stack or even make it static/global.
So nogc is enforced by the optimizer?
Yes, sadly.
What? O_o I stated that it's not and explained why doing so would be a bad idea.
 To make it sane one would need to make a list of all 
 optimization DMD makes in that regard and put them into spec as 
 mandatory for all compilers.
Apr 08 2016
parent Dicebot <public dicebot.lv> writes:
On Friday, 8 April 2016 at 12:45:59 UTC, Xinok wrote:
 On Friday, 8 April 2016 at 10:15:10 UTC, Dicebot wrote:
 On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote:
 Semantically, array literals are always allocated on the 
 heap. In this case, the optimizer can obviously place the 
 array on the stack or even make it static/global.
So nogc is enforced by the optimizer?
Yes, sadly.
What? O_o I stated that it's not and explained why doing so would be a bad idea.
It is not enforced by _backend_ optimizer as all relevant checks are done by frontend but the fact of will you get error or not does depend on semantics that are currently defined as optional optimizations. Like putting array literal on stack.
Apr 08 2016