简体   繁体   中英

warning: expression results unused

Why does the compiler issue the warning: Expression results unused in the last else statement of this code?

PowerballLottery::WinningPossibility PowerballLottery::checkTicket(PowerballTicket ticket)
{
    int count = 0;
    if (ticket.getBall1() == getball1() || ticket.getBall1() == getball2() || ticket.getBall1() == getball3() || ticket.getBall1() == getball4() || ticket.getBall1() == getball5())
        count++;
    if (ticket.getBall2() == getball1() || ticket.getBall2() == getball2() || ticket.getBall2() == getball3() || ticket.getBall2() == getball4() || ticket.getBall2() == getball5())
        count++;
    if (ticket.getBall3() == getball1() || ticket.getBall3() == getball2() || ticket.getBall3() == getball3() || ticket.getBall3() == getball4() || ticket.getBall3() == getball5())
        count++;
    if (ticket.getBall4() == getball1() || ticket.getBall4() == getball2() || ticket.getBall4() == getball3() || ticket.getBall4() == getball4() || ticket.getBall4() == getball5())
        count++;
    if (ticket.getBall5() == getball1() || ticket.getBall5() == getball2() || ticket.getBall5() == getball3() || ticket.getBall5() == getball4() || ticket.getBall5() == getball5())
        count++;
    bool match = false;
    if (ticket.getPowerball() == getpowerball())
        match = true;
    if ((count == 0) && (match == false))
        return PowerballLottery::WinningPossibility::NOTWINNING;
    else if ((count == 0) && (match == true))
        return PowerballLottery::WinningPossibility::POWERBALL;
    else if ((count == 1) && (match == true))
        return PowerballLottery::WinningPossibility::ONEPLUSPOWERBALL;
    else if ((count == 2) && (match == true))
        return PowerballLottery::WinningPossibility::TWOPLUSPOWERBALL;
    else if ((count == 3) && (match == false))
        return PowerballLottery::WinningPossibility::THREE;
    else if ((count == 3) && (match == true))
        return PowerballLottery::WinningPossibility::THREEPLUSPOWERBALL;
    else if ((count == 4) && (match == false))
        return PowerballLottery::WinningPossibility::FOUR;
    else if ((count == 4) && (match == true))
        return PowerballLottery::WinningPossibility::FOURPLUSPOWERBALL;
    else if ((count == 5) && (match == false))
        return PowerballLottery::WinningPossibility::FIVE;
    else ((count == 5) && (match == true));
        return PowerballLottery::WinningPossibility::FIVEPLUSPOWERBALL;
}

Effectively, the code is

if ((count == 0) && (match == false))
....
else if ((count == 5) && (match == false))
    return PowerballLottery::WinningPossibility::FIVE;
else
    ((count == 5) && (match == true)); //<- Expression results unused 

return PowerballLottery::WinningPossibility::FIVEPLUSPOWERBALL;

Others have already pointed out the problem the compiler was warning you about.

Now let's consider the problem it didn't warn you about: your code is much more complex than there's any good reason for it to be.

In essence, the users picks and the balls chosen in the lottery (other than the power-ball) form sets. What we care about is the size of the intersection of those two sets. The C++ standard library gives us tools to make that task a lot simpler (and it looks to me like the way you've designed your PowerBallTicket class is doing more to hinder than help too):

std::set<int> lottery { 
    getball1(), 
    getball2(), 
    getball3(), 
    getball4(), 
    getball5()
};

std::set<int> tick { 
    ticket.getball1(), 
    ticket.getball2(), 
    ticket.getball3(), 
    ticket.getball4(), 
    ticket.getball5() 
};

std::vector<int> matches;

std::set_intersection(lottery.begin(), lottery.end(), 
                      tick.begin(), tick.end(),
                      std::back_inserter(matches));

That gives us the matches between the two. From there, we have the problem of converting the number of matches (plus whether the Powerball matched) to choose which enumeration value to return. One easy way to do that is to is an array:

WinningPossibility rets[][6] = {
    { NOTWINNING, ONE, TWO, THREE, FOUR, FIVE},
    { POWERBALL, ONEPLUS, TWOPLUS, THREEPLUS, FOURPLUS, FIVEPLUS }
};

With those in place, our return looks something like this:

return rets[ticket.getpowerball() == getpowerball()][matches.size()];

The code above points toward an improvement: instead of all those getballX() member functions, you should just store the data in a set to start with, and operate directly on those sets. In this case, it looks like you have quasi-classes , with "encapsulation" that's losing a great deal, and gaining little (probably nothing).

As said from @AlexD 's answer this is primarily a problem with how you had formatted the code, and that warning appears because

else ((count == 5) && (match == true));

that statement actually isn't used to do any computation stored in a result, or making a branch decision based on it.

The

return PowerballLottery::WinningPossibility::FIVEPLUSPOWERBALL;

statement is executed regardless anyways.


Reminds a bit about the famous apple OpenSSL goto fail; bug :

 if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; /* MISTAKE! THIS LINE SHOULD NOT BE HERE */ 

You can say else <statement> or else if (<expression>) <statement> ; you have the expression without the if , which the compiler is doing its best with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM