Final variable initialization problem with exhaustive switch
John Rose
john.r.rose at oracle.com
Tue Nov 30 07:20:28 UTC 2021
On Nov 29, 2021, at 12:04 PM, Dimitris Paltatzidis <dcrystalmails at gmail.com<mailto:dcrystalmails at gmail.com>> wrote:
How can the compiler prove that the final variable will be initialized only
in the second case and not in the first too?
That differing treatment of definite assignment seems like
it should be a bug, right? But it’s not. In fact, your switch
expression can (under certain circumstances) execute
correctly without executing either of its case branches.
Switch expressions are inherently exhaustive across their cases.
Switch statements are not. This is a key difference.
You can see this if you take your code and comment out
one of the cases, say for Parity.EVEN. The switch expression
errors out at compile time, but the switch statement is a
happy camper.
Or, if someone comes along and adds a third member to Parity
(say, NEITHER) then your switch expression will either fail to
compile statically or (if not recompiled) will fail to terminate
normally at runtime (throwing something).
Meanwhile, the corresponding switch statement will happily
recompile, and (whether recompiled or not) will fall through
when Parity.NEITHER is presented. In that case, the variable
in question will not have been initialized.
This is a problem with legacy switch statements. I’m not sure
what the solution will be, although I know various alternatives
have been discussed at some point. The problem is that the
language cannot read the user’s mind, when it finds that
(a) an enum is the subject of a switch statement but (b) not
all members of the enum are mentioned in the cases. Is it
an error in a switch that was intended to be exhaustive?
Or is it just that the user (that lazy user!) didn’t want to
mention cases which needed no-op actions?
— John
More information about the amber-dev
mailing list