Konrad Rudolph
Konrad Rudolph

Reputation: 545488

“Warning: comparison is always true”

GCC (4.7.2) with -Wextra signals the following warning/error (I have -Werror enabled):

Comparison is always true due to limited range of data type [-Wtype-limits]

for the following code [try online]:

template <
    typename T,
    std::size_t N,
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
    static constexpr bool validate(T value) {
        return static_cast<std::size_t>(value) < N;
    }
};

template <typename T, std::size_t N>
struct validator<T, N, true> {
    static constexpr bool validate(T) {
        return true;
    }
};

int main() {
    // Works
    static_assert(validator<int, 4>::validate(3), "Invalid");
    // Error :-(
    static_assert(validator<bool, 2>::validate(true), "Invalid");
}

I understand why the warning would occur in a normal expression context, e.g. when I would have used the following validate function:

template <typename T, std::size_t N>
bool validate(T value) {
    return static_cast<std::size_t>(value) < N;
}

– In fact, that’s why I am using the specialised template in the first place (and note that the correct template specialisation is used, and the error in my first code is raised by the template argument, not inside the function in the unspecialised template). Is there a way around this warning? If not, isn’t that a bug in the compiler?

Upvotes: 7

Views: 1478

Answers (3)

Neil
Neil

Reputation: 55382

Here's a workaround:

template <
    typename T,
    std::size_t N,
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N>
struct validator {
    static constexpr bool validate(T value) {
        return size_t_cast(value) < N;
    }
private:
    static constexpr std::size_t size_t_cast(T value) {
        return value;
    }
};

template <typename T, std::size_t N>
struct validator<T, N, true> {
    static constexpr bool validate(T) {
        return true;
    }
};

This allows the example to compile without errors in GCC 4.7.2.

Upvotes: 1

Konrad Rudolph
Konrad Rudolph

Reputation: 545488

Since I can’t wait until this is fixed (see Jonathan’s answer) I’ve selectively disabled the warning using GCC #pragma extensions:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
static_assert(validator<bool, 2>::validate(true), "Invalid");
#pragma GCC diagnostic pop

Note that these pragmas unfortunately need to surround the calling code even though the actual error happens in the template parameter.

Upvotes: 2

Jonathan Wakely
Jonathan Wakely

Reputation: 171253

This has been fixed in GCC trunk, see PR 11856

So wait for approximately late April and use GCC 4.8 :-)

Upvotes: 11

Related Questions