On Friday, 15 July 2022 at 06:38:58 UTC, Salih Dincer wrote:
Consider null type array which is a related topic but it cannot get a null element! The first is ok, but the second is legal. So no effect, is it normal?

```d
auto p = [ null, null ];//*
  assert(
    is(typeof(null)[] :
       typeof(p)
    )
  ); /* and it has two(2) elements */

  p ~= null;             // okay
  assert(p.length == 3); // true

  p ~= [];               // legal (no error)
  assert(p.length != 4); // what! (no effect)

  assert(p[0] == []);    // true
  assert([] == null);    // right on

  import std.stdio;
  typeid(p).write(": ", p.length);
  writeln("->", []); // typeof(null)[]: 3->[]
```

Yes, this is expected.

Note that the term `null` and `[]` are special tokens that morph type to whatever is most appropriate at the time. `null` implicitly can be typed as any pointer type, or any array type. `[]` can be typed as any array type. However, it can't be implicitly typed as `typeof(null)`, which is a special unit type.

```d
typeof(null) x;
x = []; // error;
```

So consider that appending an *element type* to an array increases the array size, whereas appending an *array type* to an array adds the elements of the latter to the former. In this case, zero elements.

There are still some inconsistencies though:

```d
pragma(msg, typeof([])); // void[], likely to avoid breaking code.
void[][] arr;
arr ~= []; // does not append an element

int[] x = [1, 2];
int[] y = null; // ok, null implicitly converts to any array
x ~= y; // ok, no elements added
x ~= null; // error, does not consider the implicit conversion to int[]
```

-Steve

Reply via email to