16

Can I treat consecutive data members of the same type as a range? For example:

struct X
{
    int a, b, c, d, e;
};

X x = {42, 13, 97, 11, 31};

std::sort(&x.a, &x.a + 5);   // kosher?
fredoverflow
  • 256,549
  • 94
  • 388
  • 662

5 Answers5

15

No, this is undefined behaviour. You are treating x.a like the first element of an array, which it isn't. May work on some implementations, may raid your fridge too ;)

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • 2
    Correct, but `For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.` So you can treat it as a pointer to the first element of an array, just the length is one. – Jesse Good Sep 05 '13 at 12:20
  • 2
    @JesseGood That quote allows `X* p = &x; ++p;` to get a pointer past the end, but not what's in OP. – jrok Sep 05 '13 at 12:27
  • @jrok But for completeness: once you get said pointer to one past the end you can use it to refer to the second element *if it is there*. C++ doesn't care whence you get the pointer. Of course, if it's not there, you get the nasties. – R. Martinho Fernandes Sep 05 '13 at 15:13
  • @R.MartinhoFernandes I'm not sure what you mean. Is it there? Or is it not there? – fredoverflow Sep 05 '13 at 16:47
7

Don't do that. Compiler is free to add paddings between structure members(and at the end).

Eric Z
  • 14,327
  • 7
  • 45
  • 69
4

If this is really something you want to do, make it an array, vector or similar.

As others have said, the standard makes no guarantees about the members being stored without gaps or otherwise things that cause problems. (And to make matters worse, it will appear to work, until you compile it with a different (version of) compiler, or for another architecture some months or years later, and of course, it won't be easy to figure out what went wrong).

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
2

No, this is not possible in C++. It would be rather difficult to standarize; in this case the semantic is simple enough, but what if the struct was heterogenous?

Marcin Łoś
  • 3,226
  • 1
  • 19
  • 21
0

Generally, it's a bad idea. If you want to treat some variables as array, you should declare them as array :)

Nevertheless you can use some compiler-specific instruction to ensure that there is no padding between elements, f.i.:

#pragma pack(push, 1)  
struct X
{
    int a, b, c, d, e;
};
#pragma pack(pop)

or

struct  __attribute__((__packed__)) X
{
    int a, b, c, d, e;
};
nevermind
  • 2,300
  • 1
  • 20
  • 36