Кто-нибудь может объяснить следующий вывод кода? - PullRequest
1 голос
/ 07 мая 2019

Привет, я новичок в языке программирования C, в типах данных переменных раздел char представляет собой 1 байт, который может содержать только один символ, тогда как int равен 4 байтам, он может содержать диапазон от -2147483648 до 2147483647.Поэтому я попытался изменить размер из следующей программы.

#include <stdio.h>

int main() {
    int num = 2147483700;
    printf("%d", num);

    return 0;
}

Вывод: -

-2147483596

Я ожидал сообщение об ошибке, связанное с размером.

Ответы [ 2 ]

4 голосов
/ 07 мая 2019

Это результат преобразования вне диапазона.В этом случае делается попытка сохранить значение вне диапазона int в int.Поскольку int подписано, преобразование происходит определенным способом реализации.

В системе, использующей представление отрицательных чисел в виде дополнения до двух, это обычно означает, что значение обтекает то, что вы видите здесь.

Компиляторы не обязаны предупреждать, когда что-то вродеэто случается, но они могут, если они решили.Например, gcc не будет предупреждать с помощью -Wall -Wextra, но будет предупреждать с помощью -Wconversion.

Это поведение описано в разделе 6.3.1.8 стандарта C относительно целочисленных преобразований:

1 Когда значение с целочисленным типом преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно не изменяется.

2 В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного сложения или вычитания значения, превышающего максимальное значение, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне новоготип.

3 В противном случае новый тип подписывается и значение не может быть представлено в нем;либо результат определяется реализацией, либо определяется сигнал реализации.

0 голосов
/ 08 мая 2019

По историческим причинам компиляторы C по умолчанию очень снисходительны и допускают глупые ошибки, не мигая.

Желательно попросить компилятор получить дополнительные предупреждения и сделать эти ошибки с -Wall -Werror или даже с более строгими настройками.например, gcc -Wextra или clang -Weverything.

Вот мой след:

chqrlie$ clang -Wall -Werror overf.c
overf.c:4:15: error: implicit conversion from 'long' to 'int' changes value from 2147483700 to -2147483596 [-Werror,-Wconstant-conversion]
    int num = 2147483700;
        ~~~   ^~~~~~~~~~
1 error generated.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...