How do compilers detect number overflows when compiling?

The compiler deals with the source code as a string, so in C ++, for example, when it supports a type operator unsigned char x = 150;, it knows from type restrictions that it unsigned charmust be in the range between 0and 255.

My question is that the number 150remains a string, which compiler algorithm does it use to compare a sequence of digits - 150in this case - against type restrictions?

I made a simple algorithm to do this for type 'int' for decimal, octal, hexadecimal and low-value binary code, but I don't think the compiler does such a thing to detect overflow in numbers.

the made algorithm is encoded in C ++:

typedef signed char int8;
typedef signed int  int32;

#define DEC  0
#define HEX  1
#define OCT  2
#define BIN  3

bool isOverflow(const char* value, int32 base)
{
    // left-most digit for maximum and minimum number
    static const char* max_numbers[4][2] =
    {
        //                 INT_MAX                           INT_MIN
        {                       "2147483647",                       "2147483648" }, // decimal
        {                         "7fffffff",                         "80000000" }, // hexadecimal
        {                      "17777777777",                      "20000000000" }, // octal
        { "01111111111111111111111111111111", "10000000000000000000000000000000" }  // binary
    };

    // size of strings in max_numbers array
    static const int32 number_sizes[] = { 10, 8, 11, 32 };

    // input string size
    int32 str_len = strlen(value);

    // is sign mark exist in input string
    int32 signExist = ((base == DEC || base == OCT) && *value == '-');

    // first non zero digit in input number
    int32 non_zero_index = signExist;

    // locate first non zero index
    while(non_zero_index < str_len && value[non_zero_index] == 0) non_zero_index++;

    // if non_zero_index equal length then all digits are zero
    if (non_zero_index == str_len) return false;

    // get number of digits that actually represent the number
    int32 diff = str_len - non_zero_index;

    // if difference less than 10 digits then no overflow will happened
    if (diff < number_sizes[base]) return false;
    // if difference greater than 10 digits then overflow will happened
    if (diff > number_sizes[base]) return true;

    // left digit in input and search strings
    int8 left1 = 0, left2 = 0;

    // if digits equal to 10 then loop over digits from left to right and compare
    for (int32 i = 0; non_zero_index < str_len; non_zero_index++, i++)
    {
        // get input digit
        left1 = value[non_zero_index];
        // get match digit
        left2 = max_numbers[signExist][i];

        // if digits not equal then if left1 is greater overflow will occurred, false otherwise
        if (left1 != left2) return left1 > left2;
    }

    // overflow won't happened
    return false;
}

, float- IEEE.

, , , ?

+3
5

: . , , - .

; , , ? , , ,

6 + 5

11? , , 32769 , 32768.

+6

, , .

, .

- .

+1

, , , :

  • (, ++, a stringstream), . .

  • (, 128- ), , , , .

0

, / , atoi, atol, atof , .

.

, , ( ) .

0

( ) . , "150" 150. , , .

. , ( ), .

(, -150 unsigned char), . -150 8- ( , , 128). , , , .

Thus, the compiler has some freedoms when evaluating statements and checking semantics. All text is converted into an internal representation for tokens and values ​​(a more compact data structure). Checking for a continuous integer literal within a range for an assignment operator occurs during the semantic stage of the compilation process. Semantics are determined by the locale or company policy. Some semantics turn into compiler options and are left to the programmer.

0
source

All Articles