bug in assigning to dynamic array element

Iain Buclaw via Digitalmars-d digitalmars-d at puremagic.com
Sat Nov 1 06:56:49 PDT 2014


On 1 November 2014 13:05, ketmar via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Sat, 1 Nov 2014 12:58:26 +0000
> Iain Buclaw via Digitalmars-d <digitalmars-d at puremagic.com> wrote:
>
>> Or how about: Every side effect is evaluated LTR.  So whatever you do,
>> don't have LHS-altering side-effects on the RHS.  It may be over the
>> top to explain simply that it is questionable and potentially wrong to
>> assume that things happen in a given order.  But you may not be too
>> far off the mark to explain that when the need for an explicit order
>> is required, do it yourself.  Avoid surprises.
> the thing is that dynamic arrays tries to disguise themselves as static
> arrays. so programmer have not only to know the compiler internals to
> explain what's going on, but he have to track all types by himself.
> this is bad for all means.
>

They both infact meet each other somewhere in the middle, but that's
another matter.

This doesn't stop the fact that unless you realise that dynamic arrays
are *dynamic* - as in, the base .ptr can and will likely change if you
grow the array .length during midflight of an assignment - you will
run into these problems.

So your only solution is to pre-allocate the ptr in the GC to prevent
the .ptr from moving because it has been reallocated to another area
to accommodate growth.


> if such assigns will be left untouched, this will inevitably lead to
> subtle bugs that are really hard to find.
>

Changing the behaviour may also create new bugs that are really hard to find.


> if such assigns will be forbidden only for dynamic arrays, any sane
> person will question that. "so i can do this for char[4] and can't do
> this for char[]? and why do you have the same syntax for completely
> different things then?"
>

Some people are used to this idea. eg:

std::cout << "foo";

> if such assigns will be forbidden for any arrays... this is even worse.
> "what? your shiny language can't do what even the simpliest C compiler
> can do? now try to convince me that D is not a toy."

That - for sure - is where you're wrong. :-)


#include <assert.h>
#include <stdlib.h>

template <typename T>
struct Array
{
    size_t length;
    T* ptr;

    Array(int size) {
        this->length = 0;
        this->ptr = new T[size];
    }
};

int saveIt(Array<size_t>& list)
{
  list = Array<size_t>(1);
  return 666;
}

int main()
{
  Array<size_t> list = Array<size_t>(1);
  list.ptr[0] = saveIt(list);
  assert(list.ptr[0] == 666);
}


Looks like C++ works in the same way as D!  Go figure!

Regards
Iain.


More information about the Digitalmars-d mailing list