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

#include<stdio.h>

int main()
{

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

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


person Abhijeet Rastogi    schedule 27.01.2010    source источник


Ответы (2)


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

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

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

unsigned char c;
c = 300;

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

Целые числа без знака, объявленные беззнаковыми, должны подчиняться законам арифметики по модулю 2n, где n — количество битов в представлении значения этого конкретного размера целого числа. не переполняется, потому что результат, который не может быть представлен результирующим целочисленным типом без знака, уменьшается по модулю числа, которое на единицу больше, чем наибольшее значение, которое может быть представлено результирующим целочисленным типом без знака.

В принципе:

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

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

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

person AraK    schedule 27.01.2010
comment
numeric_limit на самом деле numeric_limits - person Abhijeet Rastogi; 28.01.2010
comment
Вы должны купить официальную документацию, если хотите, или просто зайти на open-std. org/jtc1/sc22/wg21 и бесплатно загрузите последнюю версию: open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf - person AraK; 28.01.2010
comment
Я новичок на этом сайте. Я просто хочу знать, как вы, люди, на самом деле узнаёте так быстро, что задают этот вопрос..:) Почему вас так быстро уведомляют о вопросе? - person Abhijeet Rastogi; 28.01.2010
comment
@Shadyabhi Вы можете добавить любой понравившийся тег в свои Интересные теги справа от главной страницы StackOverflow. Эти вопросы будут освещены :) - person AraK; 28.01.2010
comment
@AraK.. Итак, я имею в виду, что вы действительно продолжаете обновлять страницу, если хотите первым ответить на вопрос .. - person Abhijeet Rastogi; 28.01.2010
comment
Если UCHAR_MAX больше, чем INT_MAX, то повышение будет до unsigned int. И печать unsigned int с "%d" определяется реализацией (или возникает сигнал, определяемый реализацией). - person Alok Singhal; 28.01.2010
comment
Но для числа 300%(UCHAR_MAX+1) результат, конечно, хорошо определен, поскольку он гарантированно может быть представлен числом int. Я добавил выше для полноты. - person Alok Singhal; 28.01.2010

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

3.9.1

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

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

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

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

person UncleBens    schedule 28.01.2010