Search code examples
cinteger-overflow

Check for Integer Overflow with Boolean


This little project is based on this discussion about the best way to detect integer overflow before an operation is performed. What I want to do is have a program demonstrate the effectivity of utilizing the integer check. It should produce an integer overflow unchecked for some numbers, whereas it should quit before performing the operation if the check (-c) flag is used. The -m is for multiplication.

The program runs fine without the boolean part, but I need some help with the boolean part that conducts the highestOneBitPosition check. I am getting compilation errors after adding the true/false logic. I am not sure if I am calling and using the highestOneBitPosition function properly. Thanks!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*boolean */ 
#define true 1
#define false 0
typedef int bool;

void ShowUsage ()
{
    printf (
    "Integer Overflow Check before performing an arithmetic.\n"
    "=======================================================\n"
    "Usage:\n"
    "Integer Operant (-a, -s, -m, -d) Checked/Unchecked (-u, -c)\n"
    "Example: ./overflowcheck 2 -a 2 -u\n"
    "\n"
);
}

size_t highestOneBitPosition(uint32_t a) {
size_t bits=0;
while (a!=0) {
    ++bits;
    a>>=1;
};
return bits;
}

int main(int argc, char *argv[]) {
    if      (argc != 5) {ShowUsage (); return (0);}
    else if (strcmp(argv[2],"-m") == 0 && strcmp(argv[4],"-u") == 0)
            {printf("%s * %s = %d -- Not checked for integer overflow.\n",argv[1],argv[3], atoi(argv[1])*atoi(argv[3]));return 0;}
/*Works fine so far */
    else if (strcmp(argv[2],"-m") == 0 && strcmp(argv[4],"-c") == 0)
    {
    bool multiplication_is_safe(uint32_t a, uint32_t b) {
    a = atoi( argv[1] );
    b = atoi( argv[3] );
    size_t a_bits=highestOneBitPosition(a), b_bits=highestOneBitPosition(b);
    return (a_bits+b_bits<=32);}
        if (multiplication_is_safe==true) 
        {printf("%s * %s = %d -- Checked for integer overflow.\n",argv[1],argv[3], atoi(argv[1])*atoi(argv[3]));return 0;}
        if (multiplication_is_safe==false)
        {printf("Operation not safe, integer overflow likely.\n");}    
    }

    ShowUsage ();
    return (0);}

compilation:

gcc integer_overflow2.c -o integer_overflow
integer_overflow2.c:40:61: error: function definition is not allowed here
        bool multiplication_is_safe(uint32_t a, uint32_t b) {
                                                            ^
integer_overflow2.c:45:17: error: use of undeclared identifier
      'multiplication_is_safe'
            if (multiplication_is_safe==true) 
                ^
integer_overflow2.c:47:17: error: use of undeclared identifier
      'multiplication_is_safe'
            if (multiplication_is_safe==false)
                ^

Solution

  • [to long for a comment]

    Nested functions are not supported in C.

    Properly indented C sources might look like this:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    /*boolean */
    #define true 1
    #define false 0
    typedef int bool;
    
    void ShowUsage()
    {
      printf("Integer Overflow Check before performing an arithmetic.\n"
          "=======================================================\n"
          "Usage:\n"
          "Integer Operant (-a, -s, -m, -d) Checked/Unchecked (-u, -c)\n"
          "Example: ./overflowcheck 2 -a 2 -u\n"
          "\n");
    }
    
    size_t highestOneBitPosition(uint32_t a)
    {
      size_t bits = 0;
      while (a != 0)
      {
        ++bits;
        a >>= 1;
      };
      return bits;
    }
    
    bool multiplication_is_safe(uint32_t a, uint32_t b)
    {
      a = atoi(argv[1]);
      b = atoi(argv[3]);
      size_t a_bits = highestOneBitPosition(a), b_bits = highestOneBitPosition(b);
      return (a_bits + b_bits <= 32);
    }
    
    int main(int argc, char *argv[])
    {
      if (argc != 5)
      {
        ShowUsage();
        return (0);
      }
      else if (strcmp(argv[2], "-m") == 0 && strcmp(argv[4], "-u") == 0)
      {
        printf("%s * %s = %d -- Not checked for integer overflow.\n", argv[1],
            argv[3], atoi(argv[1]) * atoi(argv[3]));
        return 0;
      }
    
      /*Works fine so far */
      else if (strcmp(argv[2], "-m") == 0 && strcmp(argv[4], "-c") == 0)
      {
        if (multiplication_is_safe == true)
        {
          printf("%s * %s = %d -- Checked for integer overflow.\n", argv[1],
              argv[3], atoi(argv[1]) * atoi(argv[3]));
          return 0;
        }
    
        if (multiplication_is_safe == false)
        {
          printf("Operation not safe, integer overflow likely.\n");
        }
      }
    
      ShowUsage();
      return (0);
    }
    

    There however still is a bug, which you might like to find and fix yourself. Look closely what the compiler warns you about. To enable all warnings use -Wall -Wextra -pedantic for gcc.