Reversed if condition in java bytecode

esin88 :

Consider simple example

private static String isPositive(int val) {
    if (val > 0) {
        return "yes";
    } else {
        return "no";
    }
}

Here it's pretty straightforward: if val > 0 return yes else return no. But after compilation, in bytecode, this if condition is reversed:

  private static isPositive(I)Ljava/lang/String;
   L0
    LINENUMBER 12 L0
    ILOAD 0
    IFLE L1
   L2
    LINENUMBER 13 L2
    LDC "yes"
    ARETURN
   L1
    LINENUMBER 15 L1
   FRAME SAME
    LDC "no"
    ARETURN

It checks: if val <= 0 then return no, else return yes.

First, I thought that <= check is cheaper, and it's some kind of optimization. But if I change my initial code to

if (val <= 0) {
    return "no";
} else {
    return "yes";
}

it still will be reversed in bytecode:

   L0
    LINENUMBER 12 L0
    ILOAD 0
    IFGT L1
   L2
    LINENUMBER 13 L2
    LDC "no"
    ARETURN
   L1
    LINENUMBER 15 L1
   FRAME SAME
    LDC "yes"
    ARETURN

So, is there a reason for such behavior? Can it be changed to straightforward?

Grodriguez :

It is probably done like this so that the two blocks of code in the if show up in the same order in the translated bytecode.

For example, this Java code:

if (val > 0) {
    return "yes";
} else {
    return "no";
}

Translates to something like this (pseudocode):

If val <= 0, then branch to L1
return "yes"
L1:
return "no"  

Note that in the original Java code, the if condition is checked to see if the first block of code should run, while in the translated bytecode the check is done to see if the branch should be taken (skipping over the first block of code). So it needs to check a complementary condition.

Can it be changed to straightforward?

Of course it would also be possible to preserve the condition, but then you would need to reverse the order of the two code blocks:

If val > 0, then branch to L1
return "no"
L1:
return "yes"  

I would not say that this version is "more straighforward" than the previous one, though.

Anyway, why would you want to change it? Both versions should be just fine.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=456303&siteId=1