February 07, 2015
On Saturday, 7 February 2015 at 15:04:52 UTC, Iain Buclaw wrote:
> a0.ptr == a1.ptr  // false, enforced by compiler. Comparison not actually
> emitted.

I don't think that's a viable option. It would lead to completely unintuitive behavior like the following:

---
bool isEqual(T)(T a, T b) { return a == b; }

int[0] a0;
int[1] a1;

assert(a0.ptr != a1.ptr);
assert(isEqual(a0.ptr, a1.ptr));
---

David
February 08, 2015
On 7 February 2015 at 22:45, David Nadlinger via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On Saturday, 7 February 2015 at 15:04:52 UTC, Iain Buclaw wrote:
>>
>> a0.ptr == a1.ptr  // false, enforced by compiler. Comparison not actually emitted.
>
>
> I don't think that's a viable option. It would lead to completely unintuitive behavior like the following:
>
> ---
> bool isEqual(T)(T a, T b) { return a == b; }
>
> int[0] a0;
> int[1] a1;
>
> assert(a0.ptr != a1.ptr);
> assert(isEqual(a0.ptr, a1.ptr));
> ---
>

You should be able to solve this in the compiler.  For instance, can you define an array type to having a non-fixed size?

Check if you can do something in terms of:
---
int[1] a1;
int[0:18446744073709551615] a0;  // size_t.max
---

Iain.
February 08, 2015
On 8 February 2015 at 00:51, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> On 7 February 2015 at 22:45, David Nadlinger via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> On Saturday, 7 February 2015 at 15:04:52 UTC, Iain Buclaw wrote:
>>>
>>> a0.ptr == a1.ptr  // false, enforced by compiler. Comparison not actually emitted.
>>
>>
>> I don't think that's a viable option. It would lead to completely unintuitive behavior like the following:
>>
>> ---
>> bool isEqual(T)(T a, T b) { return a == b; }
>>
>> int[0] a0;
>> int[1] a1;
>>
>> assert(a0.ptr != a1.ptr);
>> assert(isEqual(a0.ptr, a1.ptr));
>> ---
>>
>
> You should be able to solve this in the compiler.  For instance, can you define an array type to having a non-fixed size?
>
> Check if you can do something in terms of:
> ---
> int[1] a1;
> int[0:18446744073709551615] a0;  // size_t.max
> ---
>

To give another clue.

int[1] a1;  Is an array type with an index type whose range is 0..0 int[2] a2;  Is an array type with an index type whose range is 0..1 int[0] a0;  Is an array type with an index type whose range is 0..-1

The hint here is the range is always 0 .. size - 1

Iain.
February 08, 2015
On 8 February 2015 at 00:51, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> On 7 February 2015 at 22:45, David Nadlinger via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> On Saturday, 7 February 2015 at 15:04:52 UTC, Iain Buclaw wrote:
>>>
>>> a0.ptr == a1.ptr  // false, enforced by compiler. Comparison not actually emitted.
>>
>>
>> I don't think that's a viable option. It would lead to completely unintuitive behavior like the following:
>>
>> ---
>> bool isEqual(T)(T a, T b) { return a == b; }
>>
>> int[0] a0;
>> int[1] a1;
>>
>> assert(a0.ptr != a1.ptr);
>> assert(isEqual(a0.ptr, a1.ptr));
>> ---
>>
>
> You should be able to solve this in the compiler.  For instance, can you define an array type to having a non-fixed size?
>
> Check if you can do something in terms of:
> ---
> int[1] a1;
> int[0:18446744073709551615] a0;  // size_t.max
> ---
>

Though having a quick skim through the llvm class documentation, doesn't seem they have a notion of this.  So maybe your best bet is to delay pushing zero-length arrays?

I will admit it is an odd special case.  And definitely in the land of WAT if someone uses this in production code.

Iain.
February 08, 2015
On Sunday, 8 February 2015 at 01:17:02 UTC, Iain Buclaw wrote:
> I will admit it is an odd special case.  And definitely in the land of
> WAT if someone uses this in production code.

Fortunately it is very trivial to add a static analysis check for this.
February 08, 2015
On Sunday, 8 February 2015 at 00:51:21 UTC, Iain Buclaw wrote:
>> I don't think that's a viable option. It would lead to completely
>> unintuitive behavior like the following:
>>
>> ---
>> bool isEqual(T)(T a, T b) { return a == b; }
>>
>> int[0] a0;
>> int[1] a1;
>>
>> assert(a0.ptr != a1.ptr);
>> assert(isEqual(a0.ptr, a1.ptr));
>> ---
>>
>
> You should be able to solve this in the compiler.  For instance, can
> you define an array type to having a non-fixed size?

I just noticed that I managed to make a typo in the example. a1 should have also been of type int[0].

In any case, the implementation on the different compiler backends is not at all what I'm talking about at this point. You proposed special comparison semantics, and I highlighted what seems to be a deal-breaker to me. All this is on the language spec level and has nothing to do with the backend implementation.

David
February 26, 2015
> Why's that? Shouldn't _all_ 0 size variables compare equal? I'd say that follows from the definition:
>
>     array1 == array2
>         <=>
>     all corresponding elements of both arrays are equal
>         <=>
>     no corresponding elements of both arrays are different
>
> For the last one, it's obvious that this applies to empty arrays: they don't even contain elements that could compare unequal.

+1.

My proposal: let the front-end handle all 0-sized types in a special way. Note that this definition includes:
* zero-length static arrays
* static arrays of 0-sized elements
* structs with no or only 0-sized elements
* void

By definition, instances of these types don't exist physically, so no memory should be allocated.
Then, at least to me it feels natural to disallow taking their addresses, or, if that's too strict for degenerate templates, to define it to be null (the address shouldn't really matter as long as the template later reads T.sizeof=0 bytes from that address and doesn't use it to compute offsets). I don't think that hacky last-element-of-variable-length-struct use-case is worth the pain, there's got to be a cleaner solution for that.

Instead, variables of these types represent purely implicit symbols.
0-sized static arrays have a compile-time length, their .ptr is implicitly defined as null.
0-sized static arrays of corresponding element type are equal as long as their lengths match, just like 0-sized structs of corresponding type are equal.

The front-end would need to fold all usages of these 0-sized variables. It would omit all declared function parameters/arguments, return values (=> void) and all other variables of size 0 for the different back-ends.
February 27, 2015
On Thursday, 26 February 2015 at 23:17:29 UTC, kinke wrote:
>> Why's that? Shouldn't _all_ 0 size variables compare equal? I'd say that follows from the definition:
>>
>>    array1 == array2
>>        <=>
>>    all corresponding elements of both arrays are equal
>>        <=>
>>    no corresponding elements of both arrays are different
>>
>> For the last one, it's obvious that this applies to empty arrays: they don't even contain elements that could compare unequal.
>
> +1.
>
> My proposal: let the front-end handle all 0-sized types in a special way. Note that this definition includes:
> * zero-length static arrays
> * static arrays of 0-sized elements
> * structs with no or only 0-sized elements
> * void
>
> By definition, instances of these types don't exist physically, so no memory should be allocated.
> Then, at least to me it feels natural to disallow taking their addresses, or, if that's too strict for degenerate templates, to define it to be null (the address shouldn't really matter as long as the template later reads T.sizeof=0 bytes from that address and doesn't use it to compute offsets). I don't think that hacky last-element-of-variable-length-struct use-case is worth the pain, there's got to be a cleaner solution for that.

D has `.offsetof`.

>
> Instead, variables of these types represent purely implicit symbols.
> 0-sized static arrays have a compile-time length, their .ptr is implicitly defined as null.
> 0-sized static arrays of corresponding element type are equal as long as their lengths match, just like 0-sized structs of corresponding type are equal.
>
> The front-end would need to fold all usages of these 0-sized variables. It would omit all declared function parameters/arguments, return values (=> void) and all other variables of size 0 for the different back-ends.

1 2 3 4
Next ›   Last »