4

In below program how do we make compiler to issue warning/error in case if there is going to be a problem with arithmetic expressions.

If an arithmetic expression is resulting into a value which exceeds the max value of their type i would like the compiler to issue warning/error.

I have compiled below program using gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) and the compilation command used is gcc int_promo_flags.c -Wall -Wextra

I was expecting a warning/error from line long long int y = x + INT_MAX;, but there was no error/warning reported.

By casting x as (long long) x we can make the the expression to yeild correct value. But are there any compiler flags to issue warning if the arithmetic expression is going to overflow its argument type.

#include <stdio.h>
#include <limits.h>

int main()
{
    int x = 1;
    long long int y = (long long) x + INT_MAX;
    printf("%lld\n", y);
    return 0;
}
IrAM
  • 1,720
  • 5
  • 18
  • `long long` is probably far bigger (8 bytes) than `INT_MAX` (4 bytes) + 1 https://godbolt.org/z/GezYEcejj – yano Sep 08 '21 at 14:10
  • The `long long` is a bit of a red herring, because the arithmetic will overflow anyway with those values, but for `int x = -1` it will not. It's up to the programmer to keep their eye on integer ranges. If that was in a function and `int x` was passed as an argument (its runtime value is unknown), would you expect a warning? – Weather Vane Sep 08 '21 at 14:11
  • `int a, b; /* ... a>0, b>0 ... */ if (a > INT_MAX - b) fprintf(stderr, "a + b overflows\n");` – pmg Sep 08 '21 at 14:12
  • 1
    @WeatherVane, I agree with you , its difficult to track entire code(if it is big) personally for these problems. I was just curious if any flag available so it will make it easier :) – IrAM Sep 08 '21 at 14:18
  • It's a matter of practice. If the arithmetic result is to be a larger type then you should know that it is expected to overflow. It's similar to the `int x=3, y=2; float z=x/y` gaffe. – Weather Vane Sep 08 '21 at 14:20

2 Answers2

5

If you use the -ftrapv flag in gcc - you can force your program to abort on integer overflow.

For instance, removing your cast and compiling with -ftrapv, your program aborts:

int x = 1;
long long int y = x + INT_MAX;
printf("%lld\n", y);
return 0;
> gcc main.c -ftrapv -o overflow
> ./overflow
fish: Job 1, './overflow' terminated by signal SIGABRT (Abort)

I don't think mainstream compilers support compile-time warning for signed integer overflows, but you can check for them manually at runtime.

Daniel Kleinstein
  • 5,262
  • 1
  • 22
  • 39
  • yes , I saw the [post](https://stackoverflow.com/questions/199333/how-do-i-detect-unsigned-integer-multiply-overflow) ,`-ftrapv` is also mentioned there. Just wanted to know during compile time , if it can be detected. – IrAM Sep 08 '21 at 14:35
  • @IrAM Unfortunately I don't think compilers provide this functionality. – Daniel Kleinstein Sep 08 '21 at 14:37
1

Finding overflows using offline analysis is a complex algorithmic problem. Likely Turing complete assuming infinite memory resources.

However, one can use a built-in sanitizers to find such overflows in runtime.

Just compile with -fsanitize=undefined option. I've removed the cast because INT_MAX is not enough to overflow long long.

#include <stdio.h>
#include <limits.h>

int main()
{
    int x = 1;
    long long int y = x + INT_MAX;
    printf("%lld\n", y);
    return 0;
}

The run produced following report:

prog.c:7:25: runtime error: signed integer overflow: 1 + 2147483647 cannot be represented in type 'int'
-2147483648

There is a variety of sanitizer and the usually produce very good reports about violations.

tstanisl
  • 13,520
  • 2
  • 25
  • 40