11

The simplest way to ask this question is with some code:

struct Point
{
    int x;
    int y;
    int z;

    int* as_pointer() { return &x; }        // works
    int (&as_array_ref())[3] { return &x; } // does not work   
};

as_pointer compiles, as_array_ref does not. A cast seems to be in order but I can't figure out the appropriate syntax. Any ideas?

1
  • 1
    So you want the compiler to pretend that x is, in fact, an array of three ints? There's no guarantee that this will work; compilers can add padding between data members in ways that are different from the way that they lay out arrays. Commented Apr 25, 2013 at 11:52

3 Answers 3

12

I find that array types are easier to deal with with a typedef:

typedef int ints[3];

Then your as_array_ref must be written so that &as_array_ref() == &x.

The following syntaxes are possible:

  1. plain C-style cast from int* to ints*:

    ints& as_array_ref() { return *( (ints*)(&x) ); }

  2. C++ style reinterpret_cast (suggested by @Mike Seymour - see also his answer). It is often considered a better practice in C++:

    ints& as_array_ref() { return *reinterpret_cast<ints*>(&x); }

  3. Cast from int& to ints& which is slightly shorter but (for me) less intuitive:

    ints& as_array_ref() { return reinterpret_cast<ints&>(x); }

Sign up to request clarification or add additional context in comments.

2 Comments

I'd rather see a C++ style reinterpret_cast to make it more obvious that something dodgy is happening. C-style casts are both dangerous and difficult to search for.
@MikeSeymour: indeed it's more C++ like. I edited my answer accordingly, thanks.
9

The cast you need to reinterpret a reference to a variable as a reference to an array is:

reinterpret_cast<int(&)[3]>(x);

Be aware that using this gives undefined behaviour; it will probably work on any sensible implementation, but there's no guarantee that there won't be padding between the members of the class, while arrays are not padded.

Comments

2

I think that what you're trying to do would be easier (and clearer/cleaner) with an union.

2 Comments

Also a very good suggestion, thanks. I normally avoid them so the thought didn't even cross my mind!
I'm not sure about cleaner: in both cases if struct-fields and arrays happen to have different padding/alignment it won't work. So unless I'm mistaken both solutions are dangerous.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.