Нужно ли использовать unsigned char
для хранения двоичных данных, как в некоторых библиотеках, которые работают с кодировкой символов или бинарными буферами? Чтобы понять мой вопрос, посмотрите на код ниже -
char c[5], d[5];
c[0] = 0xF0;
c[1] = 0xA4;
c[2] = 0xAD;
c[3] = 0xA2;
c[4] = '\0';
printf("%s\n", c);
memcpy(d, c, 5);
printf("%s\n", d);
и printf's
вывод 𤭢
правильно, где f0 a4 ad a2
- это кодировка для кодовой точки Unicode U+24B62 (𤭢)
в шестнадцатеричном формате.
Даже memcpy
также правильно скопировал бит, хранящийся в char.
Какие рассуждения могли бы отстаивать использование unsigned char
вместо plain char
?
В других связанных вопросах unsigned char
подсвечивается, потому что это единственный (байтовый/наименьший) тип данных, который, как гарантируется, не имеет дополнения по спецификации C. Но, как показал вышеприведенный пример, на результат, похоже, не влияет какое-либо дополнение как таковое.
Я использовал VС++ Express 2010 и MinGW для компиляции вышеизложенного. Хотя VC дал предупреждение
warning C4309: '=' : truncation of constant value
вывод, похоже, не отражает этого.
P.S. Это можно было бы обозначить как возможный дубликат Если буфер байтов подписан или без знака char buffer?, но мои намерения различны. Я спрашиваю, почему что-то, что, кажется, работает нормально с char
, должно быть напечатано unsigned char
?
Обновление: Для цитаты из N3337,
Section 3.9 Types
2 Для любого объекта (кроме подобъекта базового класса) тривиально тип копирования T, независимо от того, имеет ли объект допустимое значение типа T, базовые байты (1.7), составляющие объект, могут быть скопированы в массив char или без знака char. Если содержимое массива charили unsigned char копируется обратно в объект, объект должен впоследствии сохраняют свое первоначальное значение.
В свете приведенного выше факта и моего первоначального примера на компьютере Intel, где char
по умолчанию signed char
, я все еще не убежден, что unsigned char
должен быть предпочтительнее char
.
Что-нибудь еще?