gcc: warning: большое целое число неявно усекается до типа без знака - PullRequest
6 голосов
/ 28 января 2010
#include<stdio.h>

int main()
{

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

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

Ответы [ 2 ]

10 голосов
/ 28 января 2010

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

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

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

unsigned char c;
c = 300;

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

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

В основном:

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

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

происходит рекламное преобразование из unsigned char в int.

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

4 голосов
/ 28 января 2010

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

3.9.1

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...