solution for arrow vs. dot to access struct member

This is a trick so you can always use -> instead of . to access struct members.
The trick is to declare struct variables as array of one element:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
struct foo
{
    int A;
};
struct bar
{
    foo F[1];
};
void test()
{
    bar Bar[1] = {};
    Bar->F->A = 1;
}

It is not a perfect solution. for example:

1
2
3
4
5
// This no longer works:
// bar Bar[1] = InitializeBar(5);
// you have to do this
bar Bar[1];
*Bar = InitializeBar(5);

Hopefully that doesn't confuse the optimizer :)
You can still do this:

1
2
3
4
5
6
7
// This no longer works:
// bar Bar[1] = InitializeBar(5);
// you have to do this
bar Bar[1] = { InitializeBar(5) };

// or this
bar Bar[1]{ InitializeBar(5) };


But I'm not sure I like this trick too much. It makes declarations more confusing. It's not clear why it's an array at that point.

You could, of course, use the preprocessor to mitigate this "problem":

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#define VAR(Decl) Decl[1]
struct foo
{
    VAR(int A);
};
struct bar
{
    VAR(foo F);
};
VAR(bar Bar);
*Bar->F->A = 1;


Or one could use another language :P Crossing fingers for JAI...
Yes, it can be confusing but it is an array of one element so it is too much confusing.
Also it's easier than other solution:
1
2
bar Bar_ = {};
bar *Bar = &Bar_;


Yes, but JAI is not shipping before 2 years, hopefully not longer. Until then we're stuck with C++.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#define PLZ_GIMME_ARROW_FOR_STRUCT(S) S* operator -> () { return this; }

struct foo
{
    int A;
    PLZ_GIMME_ARROW_FOR_STRUCT(foo)
};
struct bar
{
    foo F;
    PLZ_GIMME_ARROW_FOR_STRUCT(bar)
};
void test()
{
    bar Bar = {};
    Bar->F->A = 1;
}


Edited by Mārtiņš Možeiko on
"Modern" C++ way :D
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
template< class T >
struct arrow_wrapper {
    T data;
    T* operator->() { return &data; }
    operator T&() { return data; }
};
struct foo
{
    int A;
};
struct bar
{
    arrow_wrapper< foo > F;
};
void test()
{
    arrow_wrapper< bar > Bar = {};
    Bar->F->A = 1;
}