It’s similar, but technically it’s not the same logic.
The ternary case is more similar to what @rapso suggested - it’s the argument to the constructor that depends on the condition, and the constructor is called regardless.
The second case makes the entire assignment conditional, so the compiler would have to do extra work on the latter code to produce the same result because it would have to look at both branches and establish what they have in common (i.e. they’re both calling the same constructor and both performing an assignment).
(That said, some versions of GCC might be able to optimise this case. I’m not sure which version of GCC is in use here.)
Either way, an if
is never 100% the same as the conditional operator, they have different semantics. Sometimes they can produce the same observable effects, but they follow different paths to get there.
This seems surprising at first, until you realise that Level
is actually a really huge type.
(Well, ‘really huge’ by Arduboy standards. On desktop you’d be laughing.)
By my calculations, sizeof(Level::entities)
alone is 672, and sizeof(Level::states)
is another 150 on top of that…
All in all I make it to be about 845 bytes.
So one Level
object plus Arduboy2
’s frame buffer (1024 bytes) already takes up 1869 of the available 2560 bytes, attempting to allocate a second Level
object is going to exhaust the RAM regardless of where it’s allocated.
There is one other option as well: placement new
.
// Manually destroy the existing object
level.~Level();
// Use placement new to construct the new object
new (&level) Level (prevScene == Scene::NEW_GAME ? menuNewGame.choice - 1 : level.levelNo + 1);
Using if
that would be:
// Manually destroy the existing object
level.~Level();
if(prevScene == Scene::NEW_GAME)
// Use placement new to construct the new object
new (&level) Level (menuNewGame.choice - 1);
else
// Use placement new to construct the new object
new (&level) Level (level.levelNo + 1);
Though personally I’d advise sticking to the conditional operator anyway because it just makes more sense in this case.
If the only statement inside the body of both the if
and the else
is an assignment to the same variable then a conditional operator nearly always makes more sense anyway.
(Note: In this case you could get away with not calling the destructor, and it’ll be optimised away anyway because in this case Level
’s destructor doesn’t do anything, but there are some types that would require it, so I added it for the sake of completion/correctness.)