I have this code, which is used to build a graphic interface on a LCD display on a controller; the code is compiled for 2 different architectures using both AVR and PIC32:
FishinoTftGuiLabel *l1;
FishinoTftGui
.Page(F("Page1"))
.Label(50, 140, 0, 24, LabelAlign::Left, F("Slider value:"))
.getElement(l1)
--
.Label(l1->x() + l1->w() + 10, 140, 0, 24, LabelAlign::Left, F("pippo"))
;
Each member function return the same object (or a related one); so for example the Label() function returns the FishinoTftGuiLabel reference, which can be used for chaining other calls.
The getElement(T *&) is simply a way to get a pointer to current object, which can be used in following calls without breaking the chain and having to use intermediate variables for each object; the -- operator returns back to the containing Page object.
My problem is that the 'l1' pointer, which should be set by getElement on first Label creation, is set AFTER the whole stuff terminates, but just on AVR platform; on PIC32 the evaluation is ok.
So, on PIC32 the order is following:
1) the first Label statement is evaluated and the label is created
2) the getElement(l1) is executed, storing the reference of first label
3) the second Label statement is evaluated; the l1->x() are correctly using the Label1 reference
On the AVR platform, this happens:
1) All arguments of ALL Label() calls get evaluated at first, so the l1->x() crashes, because of calling an uninitialized object's member
2) The Label() functions are evaluated next
My question : is it a compiler bug, or the evaluation order between chained calls is not guaranteed in this case ? Is there a way to force the right evaluation order, without having to break the whole stuff in multiple statements ?