abrand
abrand

Reputation: 43

Renaming (aliasing) array elements C

Not sure what is "good practice" or considered more "correct". I have an array, I want to access individual elements by names other than arrayname[]. I could use #defines or pointers, probably other ways also.

Example:

#define value1 myarray[1]

int myarray[SIZE];
value1 = 5;

or

int myarray[SIZE];
int *ptr;
ptr = &myarray[1];
*ptr = 5;

Seems to me the #define route is simpler and uses less memory, but could bring up a bunch of issues I am not aware of. Any insight would be great, I like to keep my code following the general accepted standards wherever possible.

*Edit:Maybe there is a better way altogether. My end goal is to get an array that will be sent out a peripheral port. However the data is comprised of very different data sets, and a single array name would not be representative of the data being assigned. My memory is quite limited so I would like to avoid double storing each value.

Upvotes: 4

Views: 2771

Answers (6)

Goz
Goz

Reputation: 62333

The non-define method allow you a degree of type correctedness that is not available from the second.

Furthermore the actual code generated by any sane compiler will be identical for both.

All in I'd waaay prefer the 2nd as it is instantly obvious what is going on. The other bugger is that the #define could cause problems outside of the scope of the area you are actually dealing with.

Its much more sensible using the latter as it means it is less likely that someoen else will come along and mess it up at a later occasion ...

Upvotes: 0

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275600

enum {SIZE = 100};

struct Mapping {
  int unused1;
  int value1;
  int unused2;
};

Mapping& AsMapping( int(&array)[SIZE] ) {
  return *reinterpret_cast<Mapping*>(&array);
}

int arr[SIZE];
AsMapping(arr).value1 = 5;
Mapping& values = AsMapping(arr);
values.value1 = 5;

This requires next to no memory, and optimizers should be able to erase everything. Meanwhile, it is reasonably maintainable.

Setting up the alignment on your structs may be a requirement that you have to be careful of.

Upvotes: 1

Leonid Volnitsky
Leonid Volnitsky

Reputation: 9144

Why not references?

int A[3];  
int& a1=A[1];

Upvotes: 2

Kane Anderson
Kane Anderson

Reputation: 563

You could do something like this

typedef enum
{
    foo = 0;
    // ... more named values
    bar = SIZE;
} Thing;

int value[SIZE];
value[foo] = 5;

Using an enum as an array index

Upvotes: 0

Sebastian
Sebastian

Reputation: 1889

unions are another way to alias variables. But don't take this as a recommendation. They are dangerous (unportable) if you rely on the aliasing. You should only use them to optimize memory usage, for variables which you don't need at the same time.

Upvotes: 1

David Duncan
David Duncan

Reputation: 1215

I propose a third option, by example:

#define VALUE1_IDX  1

int myarray[SIZE];
myarray[VALUE1_IDX] = 5;

The advantage of this over #1 is that it's still obvious that you're making use of myarray, and the advantage over #2 is, like you said, avoiding pointers. I would suspect, but haven't verified, that with optimization there is going to be no extra memory usage with option #2, despite that it seems intuitive that it would.

I think the best solution will vary with the situation, and I think either of your two options could be defensible in the right context.

Edit: To echo Kevin's comment, it's also first worth checking if it's possible to avoid using an array when you're not handling the values collectively. I realize that there are certainly situations where this does not apply, such as if you read in a long message and want to simply pull out a couple of key values.

Upvotes: 5

Related Questions