die() or return() in switch() with braces
LadyCailinBot opened this issue ยท 5 comments
CMDHELPER-2985 - Reported by PseudoKnight
There's some odd behavior when die() or return() is in a switch when using brace syntax. (build 2784) Example:
switch('b') {
case 'a':
die('failure');
case 'b':
msg('success');
}
# No output
Even stranger is when you change this:
switch('b') {
case 'a':
if(true) {
die('failure');
}
case 'b':
msg('success');
}
# No output
To this:
switch('b') {
case 'a':
if(false) {
die('failure');
}
case 'b':
msg('success');
}
# Output 'success'
There are some scripts where this problem doesn't occur, and it's not clear what the difference is.
Comment by LadyCailin
Undoubtably this is due to optimization issues. if(false){} will compile out, which means that in the following case:
switch(@a){
case 'a':
if(false){
msg('hi');
}
case 'b':
msg('boo');
}
you end up with the following equivalent (that is actually not equivalent):
switch(@a){
case 'a':
case 'b':
msg('boo');
}
I'll have to look into this. I think I need to have two priorities of optimization, and let switch optimize before the code inside it, and automatically add breaks and such. As far as with returns/dies, this is likely because the condition is a terminal statement, which has special handling in the optimizer.
Comment by PseudoKnight
Check. if(false){} is a bad testing method. I used it to see if die() had the same effect when nested, as it's not clear why some scripts are working fine with die() in switches. This is a strange compile optimization to me, as you'd never use it except in testing. If something evaluated to false every time the script ran, instead of optimizing it (hiding it), it should probably give a compile warning.
Comment by LadyCailin
That's not good, actually. For instance, using the function_exists method. If you use a function that may or may not exist, the fact that the function doesn't exist isn't any sort of warning case. The following if statement will always be removed:
if(function_exists('blah')){
blah();
}
Once I get const/final variables, the same thing should apply.
final/const @debug = false;
if(@debug){
do_some_debug_logic();
}
Looking even further down the road, certain other values, such as compiler environment "constants" can be used to further optimize code, as well as support custom compiler errors, etc.
if(OS::isWindows()){
windowsOnlyCode();
} else if(OS::isMac()){
macOnlyCode();
} else if(OS::isLinux()){
linuxOnlyCode();
} else {
compiler_error('Unsupported OS');
}