Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell compiler the "range" of a #define (-Wtype-limits warning)

In my code, I need to saturate a variable uint32_t var within a range [MIN, MAX]. MIN and MAX are defined as macros, so I can change these values easily inside a header file.

Header:

#define MIN    (0)
#define MAX    (1000)

Code:

if(var > MAX){
    var = MAX;
}else if(var < MIN){
    var = MIN;
}

When I now use compiler flag -Wtype-limits, I get a warning that the second check var < MIN is always false. This warning suggests that I can remove the second comparison.

This makes sense as long as I define #define MIN (0) but, when changing this to let's say #define MIN (10), then the second comparison is mandatory.

So my question: How can I tell the compiler, that MIN can be any value greater or equal zero?

like image 596
paul_schaefer Avatar asked Jan 25 '23 06:01

paul_schaefer


2 Answers

The simplest solution is just use <= instead of <

if (var >= MAX) {
    var = MAX;
} else if (var <= MIN) {
    var = MIN;
}

But you should avoid macros if possible and just declare constants instead. Besides always use the U suffix when you work with unsigned values to avoid signed-unsigned incompatibility warnings. In fact it's quite interesting to see that if I use #define like that I get a warning in GCC but not Clang, and when I change to const and add the U suffix then I get no warning with GCC but one with Clang

like image 118
phuclv Avatar answered Jan 27 '23 16:01

phuclv


This solves the issue:

int main(void) {
    unsigned int var = rand();

    if (var > MAX){
        var = MAX;
    }
#if MIN > 0
    else if (var < MIN) {
        var = MIN;
    }
#endif

    printf("token = %u\n", var);
}

Edit: reduce "dirtiness" by making it clear what the two cases are.

uint32_t saturate(uint32_t var)
{
#if MIN > 0
    if (var > MAX){
        var = MAX;
    }
    else if (var < MIN) {
        var = MIN;
    }
#else
    // Only need to do the upper bound
    if (var > MAX){
        var = MAX;
    }
#endif
    return var;
}
like image 35
stark Avatar answered Jan 27 '23 15:01

stark