Question Details

No question body available.

Tags

c++ coverity

Answers (1)

Accepted Answer Available
Accepted Answer
February 13, 2026 Score: 5 Rep: 56 Quality: High Completeness: 60%

Your array creates named constants: APPLE=0, ORANGE=1, PEAR=2, NUMFRUIT=3. But the underlying type is int, and the compiler doesn't restrict what values a FRUITID variable can actually hold. Only values 0, 1, 2 get through the if, so the array access is always safe.

Coverity analyzes the type of id. It knows FRUITID is backed by int. So it reasons:

id is an int
int can be -2147483648 to 2147483647
I see a check: id >= 0 && id < 3
But do I trust that check constrains the array access?
...i'm not sure. I'll flag it anyway

Why the distrust? Because this is perfectly legal C++:

void somewhereelse() {
    FRUITID bad = staticcast(100);
    checkFruit(bad);  // Ccompiles fine. No warning.
}

Or worse:

void readfromfile(int value) {
    checkFruit(staticcast(value));  // value could be anything
}

Your check catches these at runtime. But Coverity's analyzer doesn't always propagate the constraint from your if condition to the array index operation. It's a limitation of its dataflow analysis for enum types.

The main issue here is C++ enums are "strongly named" but "weakly typed." The names suggest a closed set; the type allows anything. Coverity errs on the side of caution because it can't prove all callers behave.

You have a few options depending on what trade-offs you're willing to make here-

1. Suppress the warning (easiest, if your check is genuinely sufficient):

bool checkFruit(const FRUITID id) const {
    if (id >= 0 && id < NUMFRUIT) {
        // coverity[overrun-local]
        return fruit[id].bitten;
    }
    return false;
}

You're telling Coverity "I know what I'm doing here."

2. Use an intermediate int variable (I am assuming this should alos pass Coverity):

bool checkFruit(const FRUITID id) const {
    int index = staticcast(id);
    if (index >= 0 && index < NUMFRUIT) {
        return fruit[index].bitten;
    }
    return false;
}

Coverity tracks int bounds more reliably than enum bounds.

3. Use enum class with a fixed underlying type (comes from C++11+):

enum class FRUITID : unsigned int { APPLE = 0, ORANGE, PEAR, NUMFRUIT };

This makes the type explicit and can help some analyzers reason better. You'll need staticcast to use it as an index though.

4. Use std::array with .at() for bounds-checked access:

std::array fruit;

bool checkFruit(const FRUITID id) const { try { return fruit.at(staticcast(id)).bitten; } catch (const std::outof_range&) { return false; } }

Overkill for most cases, but makes the bounds check explicit and exception-safe.