Array assignment issue, warning wanted


#1

I spent quite some time debugging and scratching my head over a misterious bug that I narrowed down to the fact that I was unable to assign an element in an Array:

Array<MyStruct> array; ... if (array[i].field == something) array[i].otherfield = whatever;

I found the assigment simply doesn’t work, ok so, I could live with that, but I really expected a warning or compiler error here.

Would it be possible to catch that pitfall with some warning?


#2

This test app generates two compile errors:

#include "juce.h"

struct MyStruct
{
  int field;
  int otherfield;
};

int main (int, char**)
{
  ScopedJuceInitialiser_GUI jucelib;

  Array <MyStruct> array;

  array.add (MyStruct ());

  array [0];
  array [0].otherfield;
  array [0].otherfield = 1; // error
  
  if (array[0].field == 0)
      array[0].otherfield = 1; // error

  return 0;
}

#3

I do not get any errors here with XCode 3.

Obviously I missed the fact that [] returns a copy of the element rather than a reference, unlike getReference(). Intuitively, I would expect the opposite. It is probably too late to change this, as it might break existing code. I might also miss important details here.

The missing error message might be gcc specific.


#4

Well, the docs do state it’s only meant to be used for primitive types, as it stores/retrieves copies; OwnedArray/ReferenceCountedArray should be used if you want to use more complex objects.


#5

It has to return a copy because if your index is out-of-range, it returns a null/default object, which it has to construct, so it can’t return a reference to it (ok, I guess it could probably have some kind of static null object hanging around and return a reference to that, but depending on the type of object, that might have side-effects).

But I’m surprised you didn’t get an error or at least a warning - maybe you need to crank up your warnings level?


#6

A flat struct with primitive fields is a relatively primitive type, IMO.

I’m fine with the Array behavior, just missing an error message. As [] is used to mimic the syntax of C arrays, and I appreciate that because it makes code a lot easier to read, it easily happens that you use it for assignment too.

@jules: What particular warning would cover this for gcc?


#7

Too primitive! You’d need to at least provide a default constructor, or you’ll have a bunch of uninitialised values getting used. You’ll probably also want an operator==. The Array class expects an object that has copy-by-value semantics.

Hmm, looking at the function again, I’m a little puzzled about why I didn’t make it return a const ElementType (same as getUnchecked), which would of course have avoided your problem… I think that might just have been an oversight, which I’ll fix!

BTW if you’re iterating an array, it’d be much better to use getReference() anyway, because not only does it not make a copy, it also doesn’t bother checking whether the index is in range each time.


#8

sorry, I was only half paying attention when I read the original post :slight_smile: I didn’t notice the actual thing you had an issue with (array[i] = x).

I’d have thought that operator would return a const, (like getUnchecked()), but the docs show that it doesn’t.

[curses, jules beat me to it!]