c: введите приведение значений char в unsigned short - PullRequest
0 голосов
/ 13 ноября 2018

начиная с фрагмента псевдокода:

char a = 0x80;
unsigned short b;
b = (unsigned short)a;
printf ("0x%04x\r\n", b); // => 0xff80

В моем нынешнем понимании "char" по определению не является ни символом со знаком, ни символом без знака, а своего рода третьим типом подписи.

как получилось, что «а» сначала расширяется от (возможно, в зависимости от платформы) 8-битного хранилища до (возможно, опять-таки, для конкретной платформы) 16 битов подписанного короткого замыкания, а затем преобразуется в неподписанное короткое замыкание?

существует ли стандарт c, который определяет порядок расширения?

Содержит ли это стандартное руководство каким-либо образом о том, как бороться с тем третьим типом подписи, которым является "чистый" символ (я назвал его один раз X-символом, x для неопределенной подписи), чтобы результаты были по меньшей мере детерминированными?

PS: если вставить оператор «(unsigned char)» перед «а» в строке назначения, то результат в строке печати действительно изменится на 0x0080. таким образом, только два приведения типов подряд обеспечат ожидаемый результат для определенных намерений.

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

char имеет подпись, определяемую реализацией.Он может быть как подписанным, так и неподписанным, в зависимости от компилятора.В некотором смысле верно, что char является третьим типом символов, см. this .char имеет недетерминированную (непереносимую) подпись и поэтому никогда не должен использоваться для хранения необработанных чисел.

Но это не имеет значения в этом случае.

  • На вашемкомпилятор, char подписан.
  • char a = 0x80; вызывает преобразование типа 0x80, который является int, в char, специфичным для компилятора.Обычно в системах дополнения 2 это будет означать, что char получает значение -128, как здесь, похоже, имеет место.
  • b = (unsigned short)a; вызывает преобразование из char в unsigned short 1) .C17 6.3.1.3 Целые числа со знаком и без знака затем говорят:

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

    Значение, превышающее максимальное значение, будет 65536.Таким образом, вы можете думать об этом как -128 + 65536 = 65408.

  • Шестнадцатеричное представление без знака 65408 равно 0xFF80.Никакое расширение знака не происходит нигде!


1) Приведение не требуется.Когда оба операнда = являются арифметическими типами, как в этом случае, правый операнд неявно преобразуется в тип правого операнда (C17 6.5.16.1 §2).

0 голосов
/ 13 ноября 2018

Тип char не является "третьей" подписью.Это либо signed char, либо unsigned char, и какой из них определяется реализацией.

Это продиктовано разделом 6.2.5p15 стандарта C :

Три типа char, signed char и unsigned char вместе называются типами символов .Реализация должна определять char, чтобы иметь тот же диапазон, представление и поведение, что и signed char или unsigned char.

. Похоже, что в вашей реализации char совпадает сsigned char, поэтому, поскольку значение отрицательное и тип назначения не имеет знака, его необходимо преобразовать.

В разделе 6.3.1.3 указано, как происходит преобразование между целочисленными типами:

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

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

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

Поскольку значение 0x80 == -128 не может быть представлено в unsigned short, происходит преобразование в параграфе 2.

...