Sometime in the gcc 4.5 era, a warning for the following expression was introduced and subsequently fixed apparently the development of the 10.x versions, i.e. newer compilers do no longer produce the warning.
The expression producing the warning immediately precedes the final return from main and reads as follows:
$ gcc -Wsign-conversion -o /tmp/banana /tmp/banana.c
/tmp/banana.c: In function ´main´:
/tmp/banana.c:40:5: warning: conversion to ´long unsigned int´ from ´int´ may change the sign of the result [-Wsign-conversion]
40 | : ((a_default <= a_max)
| ^
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
/* generic parsing function to make sure we retrieve values the
* compiler cannot make assumptions about without invoking UB
* (hopefully) */
static long
parse_long(const char *str)
{
char *endptr = NULL;
long val = strtol(str, &endptr, 0);
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0)) {
perror("strtol");
exit(EXIT_FAILURE);
}
if (endptr == str) {
fputs("No digits were found\n", stderr);
exit(EXIT_FAILURE);
}
return val;
}
int main(int argc, char **argv)
{
if (argc < 2) return 1;
errno = 0;
int val = (int)parse_long(argv[1]);
size_t a_default = 1024;
if (argc > 2)
a_default = (size_t)parse_long(argv[2]);
static const size_t a_max = 4096;
/* the above only serves to make sure the compiler cannot assume
* much about the values of a_default and val */
size_t a = (val > 0)
? (size_t)val
: ((a_default <= a_max)
? a_default : a_max);
return a > 0;
}
I now want to get rid of this warning, though incorrect, with as little fuss as possible. One non-obvious way I already found is changing val
to long
type.
While the obvious solution is to upgrade compilers, versions 8 and 9 of gcc are still very common production compilers and I'd really like to build without warnings on RHEL 8.x and Debian oldstable and Ubuntu 20.04. Any alternatives to prevent the warning or perhaps tell me how that part of the program is indeed doing something wrong is appreciated.