If - else possible bug?

Hi,

I’m developing an Android app in Kotlin (Not the first app, so I’m experienced in Kotlin somewhat already).

I`ve found an interesting bug(?) regarding the if - else conditionals.
On this screenshot You can see that I’m running a debugger in Android Studio running my code on an emulator:

As You can see the debugger is stopped on the breakpoint in line 48.

Why is it interesting? Because in line 45 there’s an if (!hasFocus) condition, and You can see that hasFocus Boolean is false. So in this case the else branch should not be called at all. (For the sake of completeness, in this case the previous breakpoint in line 46 was also run on…).

I put the code here, so You can copy it:

val etFirstName = v.findViewById<EditText>(R.id.addPatient_et_firstName)
    etFirstName.setOnFocusChangeListener { v, hasFocus ->
        var origBg: Drawable? = null
        if (!hasFocus) {
            origBg = v.background
        } else {
            if (origBg != null) {
                v.background = origBg
            }
        }
    }

As I was playing around I tried to change the if condition to “if (hasFocus.not()) …” and “if (hasFocus == false) …” but the situation remained the same.

What changed the scenario was when I added an “else” branch to the “if” conditional inside the outer conditional’s “else” branch:

val etFirstName = v.findViewById<EditText>(R.id.addPatient_et_firstName)
    etFirstName.setOnFocusChangeListener { v, hasFocus ->
        var origBg: Drawable? = null
        if (!hasFocus) {
            origBg = v.background
        } else {
            if (origBg != null) {
                v.background = origBg
            } else {
                val i = 0 //Do whatever...
            }
        }
    }

This time when hasFocus was false the code inside the outer “else” branch was not run.

So my assumption is that in the original scenario the compiler tries to optimize the outer if-else statement, and finds that the else branch contains only one single-branch if condition, hence it would treat the outer else branch as if it would be an “else if” branch of the outer conditional.

In my opinion this should not happen at all, since the condition governing the decision at the beginning made the code go in the “if” branch, whatever is in the “else” branch should not be called, even if it is a another condition.

Cheers,
Lenard Nagy

The chances of a bug in the compiler for such a fundamental and frequently-used structure, without anyone else noticing, seem very low indeed. — I’d be a lot less surprised by a bug (or unexpected feature) in the debugger, though.

It’s not something easily reproduced, so it would be a very rare bug as well.
https://pl.kotl.in/aPW6EyIv5
If this is something you think is really a bug in the compiler and not just the debugger( which I agree is more likely) you should create an issue at https://kotl.in/issue. You should probably add a link to your project there as well + information about your kotlin/jvm/jdk version and your operating system. That way the kotlin team can take a look.
Also you could take a look at the generated jvm bytecode if you know how to read that. It shouldn’t be to hard to figure out if the inner if-condition is executed that way.

Hi,

It seems to be a debugger bug indeed. I have created a simple function to reproduce, but the only thing that happens is that the debugger stops at the inner if in the else branch, bet even if the condition of the inner if evaluates to true the code inside is not executed. The sample code is similar to Yours, but debuggable in Android Studio.

https://pl.kotl.in/aqklfdPV0

Thanks for the help, I’ll go and post this code on the debugger’s maintainer list.

Cheers,
Lenard