In the following code:

for (int i = 0;i < num_neighbors && i != msg.source && neighbors[i].status == EDGE_STATUS_BRANCH;i++) {

loop body was never entered.

Where as after making this change:

for (int i = 0;i < num_neighbors;i++)
       if (i != msg.source && neighbors[i].status == EDGE_STATUS_BRANCH) {

the body inside if branch was entered.

Why is the condition in the first for loop evaluated to false but not the second one?

Your first loop is never going to execute if
(a) 0 is equal to msg.source or
(b) neighbors[0].status is not equal to EDGE_STATUS_BRANCH

By putting those checks in the loop exit condition, if the first element doesn't pass all criteria, the loop exits immediately. (If the first element passed, the loop would end execution the first time it came across an element that failed.) By seperating the source/status logic from the loop iteration limit, the loop can perform as (I assume) you intend by checking the source and status values for each element of neighbors.