views:

737

answers:

6

Found an interesting use of a typedef that I really didn't see the need for.

typedef int Color[3];

So then the use would be:

Color pants;
pants[0] = 0;
etc.

Using the typedef through ptrs was creating strange looking code that wasn't clear.

Why not just use a struct?

struct Color {
int r;
int g;
int b;
};

Color pants;
pants.r = 0;
etc.

You could use a union to express the vars as an array or individually, which is wonky, but still clear that it is somehow more complex than a single value.

Can someone offer insight as to the merit of using the typedef'd array vs. struct?

+2  A: 

You want the array expression to be able to loop.

So if you must have the [rgb] forms, you use a union, but that makes for more typing.

::sigh::

dmckee
+6  A: 

Could be that the structure was not aligned the way the original coder wanted. maybe it was padded to 16 or 32 bits. Creating the array ensures no structure padding takes place. Was this passed into a driver or to some hardware device?

gbrandt
Nice. Works without worrying about compilation flags or `pragma`s
dmckee
A: 

The possible padding might become a problem when using an array of structs, as you might have problems converting between that and targets expecting tightly packed RGBs. In that case, make sure that the padding is exactly what you expect, using pragma pack() for instance.

As to whether .x or [] is better, you can overload operator[] for the struct (using a switch in this case). Any decent compiler will optimise this to be equivalent to static_cast<int*>(this)[index], so there is no performance loss. You can of course go with the union, but it doesn't help much. Another possibility is to implement .x () etc. in terms of [].

Anyway, I would recommend using the struct, as you don't loose anything (you can still convert an array of Color to int*, but you can write algorithms easier when taking a struct than when taking an int* -- for instance, if you want luminance, it's easier IMAO to have a nice member/free function taking a Color instead of an int*, because with the int, you can never be sure whether it's RGB, RGBA, YoCoCg while with the Color, you can enforce that.

Last but not least, a struct gives you the possibility to initialize all members to valid/sane/debug values, if wanted.

Anteru
+4  A: 

One more advantage of the struct form: if you ever need to pass the Color to a function and then take its size:

void foo (Color c)
{
    size_t s = sizeof(c);
}

If you use the array form, c will be interpreted as a Color * (arrays are passed via a pointer to their first element) and sizeof(c) will be equal to sizeof(int*). Been there, done that, got bitten there.

Edit: the struct form will behave as (naively) expected.

LaszloG
why not just do sizeof(Color)?
newacct
If you ever change the type of the variable you won't have to update the code in two (or more) places. Yes, I know that multifile search-replace, sed and Visual Assist are your friends but still I prefer not to worry about it.
LaszloG
+4  A: 

Using plain array is a bad idea for several reasons.

  • The type int[] decays to int * when used in parameter list.
  • You cannot use operator= to assign arrays.

Either struct or boost::array would serve the purpose much better.

avakar
+1 Except it won't decay when passed by reference, to add confusion.
UncleBens
UncleBens: upvoted your comment: very true. A more extensive discussion can be found on SO here: http://stackoverflow.com/questions/1328223/sizeof-array-passed-as-parameter
LaszloG
A: 

I guess the array was used as a tuple, so boost::tuple could be considered as an alternative that better shows the intend.

stefaanv