Signed overflow / unsigned wrap-around

I've recently read this:
https://lwn.net/ml/linux-kernel/20240122235208.work.748-kees@kernel.org/

Trying to experiment a bit with what I learned:

   $ cat wrapme.c
   #include <stdint.h>
   #include <err.h>
   #include <stdlib.h>
   #include <stdio.h>
   #include <limits.h>

   int main(int argc, char **argv)
   {
       int val, ival;

       if (argc < 2)
           errx(1, "Usage: %s VALUE", argv[0]);

       val = INT_MAX;
       ival = atoi(argv[1]); // feeling lazy today.

       printf("will it overflow?\n");
       if (val + ival < val)
           printf("It will overflow\n");
       else
           printf("It won't overflow\n");

       val += ival;
       printf("%d\n", val);
       return 0;
   }

Compiled with different options...

   $ make
   gcc -o ftrapv -ftrapv wrapme.c
   gcc -o fwrapv -fwrapv wrapme.c
   gcc -o default wrapme.c

How will it behave upon signed integer overflow?

   $ ./fwrapv 0
   will it overflow?
   It won't overflow
   2147483647

   $ ./fwrapv 1
   will it overflow?
   It will overflow
   -2147483648

   $ ./ftrapv 0
   will it overflow?
   It won't overflow
   2147483647

   $ ./ftrapv 1
   will it overflow?
   Aborted (core dumped)

   $ ./default 0
   will it overflow?
   It won't overflow
   2147483647

   $ ./default 1
   will it overflow?
   It won't overflow
   -2147483648