gcc: предупреждение: большое целое число, неявно усеченное к неподписанному типу

#include<stdio.h>

int main()
{

    unsigned char c;
    c = 300;
    printf("%d",c);
    return 0;
}

Вывод всегда предсказуем или его неопределенное??

6
задан Abhijeet Rastogi 27 January 2010 в 23:55
поделиться

2 ответа

Извините за первый ответ, вот объяснение из стандартов C ++ :)

Является ли вывод каким-либо образом предсказуемым или его undefined ??

Это предсказуемо. В этом коде есть два момента, на которые следует обратить внимание: Во-первых, присвоение значения, которое тип unsigned char не может содержать:

unsigned char c;
c = 300;

3.9.1 Основные типы (стр. 54)

Беззнаковые целые числа, объявленные беззнаковыми, должны подчиняться законам арифметики по модулю 2n, где n - количество бит в представлении значения , которое конкретный размер целого числа. 41)
...
41) Это означает, что арифметика без знака не переполняется, поскольку результат не может быть представлен результирующий беззнаковый целочисленный тип сокращен по модулю числа, которое на больше наибольшего значения, которое может быть представлено результирующим { {1}} беззнаковый целочисленный тип.

В основном:

c = 300 % (std::numeric_limits<unsigned char>::max() + 1);

Во-вторых, передача % d в строке формата printf для печати переменной unsigned char .
Этот ysth понял все правильно;) Нет неопределенного поведения, потому что рекламное преобразование из unsigned char в int происходит в случае вариативных аргументов !

Примечание: вторая часть ответа является перефразированием того, что было сказано в комментариях к этому ответу , но изначально это не мой ответ.

10
ответ дан 8 December 2019 в 17:21
поделиться

Результат назначения должен быть предсказуемым:

3.9.1

4 целых числа без знака, объявленные без знаки, подчиняются законам арифметики модуля 2 n Где n - количество битов в значении представления этого конкретного размера целочисленного числа.17)

17) Это подразумевает, что арифметика без знака не переполняется, потому что результат, который не может быть представлен полученным целочисленным типом без знака, уменьшается модуль Номер, превышающий наибольшее значение, которое может быть представлено полученным целочисленным типом без знака.

Кроме того, SizeOf (CHAR) определяется как 1, а Sizeof (unsigned char) = sizeof (char), поэтому вы должны увидеть тот же результат независимо от внедрения (предполагая, что у вас нет байтов с забавными размерами, отличными от 8).

Однако предупреждение говорит вам, что результатом, вероятно, не то, что вы предполагаете (например,, возможно, вы переоценили размер типа без знака?). Если это то, что вы собирались, почему бы не написать 300% (1 << CHAR_BIT) (Предполагая, что 300 каким-то важным для вас)?

4
ответ дан 8 December 2019 в 17:21
поделиться