Может кто-нибудь объяснить, как подписанность char зависит от платформы? - PullRequest
10 голосов
/ 31 июля 2009

Я недавно читал, что различия между

char
unsigned char

и

signed char

зависит от платформы.
Я не могу разобраться с этим? Означает ли это, что битовая последовательность может изменяться от одной платформы к следующей, т.е. platform1, знак - первый бит, platform2, знак может быть в конце? как бы вы код против этого?

По сути, мой вопрос связан с этой строкой:

typedef unsigned char byte;

Я не понимаю актуальности вывесок?

Ответы [ 6 ]

18 голосов
/ 31 июля 2009

Предположим, что ваша платформа имеет восьмибитные байты, и предположим, что у нас есть битовая комбинация 10101010. Для signed char это значение равно минус 86. Для unsigned char, однако, та же самая битовая комбинация представляет 170. Мы не сдвинули биты; это одни и те же биты, интерпретируемые двумя разными способами.

Теперь для char. Стандарт не говорит, какая из этих двух интерпретаций должна быть правильной. char с битовой комбинацией 10101010 может быть либо & minus; 86 или 170. Это будет одно из этих двух значений, но вы должны знать компилятор и платформа, прежде чем вы можете предсказать, что это будет. Некоторые компиляторы предлагают переключатель командной строки, чтобы контролировать, какой это будет. Некоторые компиляторы имеют разные значения по умолчанию в зависимости от того, на какой ОС они работают, поэтому они могут соответствовать соглашению об ОС.

В большинстве кодов это действительно не должно иметь значения. Они рассматриваются как три различных типа для целей перегрузки. Указатели на один из этих типов не совместимы с указателями на другой тип. Попробуйте позвонить strlen с signed char* или unsigned char*; это не сработает.

Используйте signed char, если вы хотите однобайтовый числовой тип со знаком, и используйте unsigned char, если вы хотите однобайтовый числовой тип без знака. Используйте просто старый char, когда вы хотите держать символы. Это то, о чем думал программист, когда писал typedef, о котором вы спрашиваете. Имя «байт» не имеет смысла для хранения символьных данных, тогда как имя «unsigned char» имеет в своем названии слово «char», и это заставляет некоторых людей думать, что это хороший тип для хранения символов, или что Рекомендуется сравнить его с переменными типа char.

Поскольку вы вряд ли будете выполнять общую арифметику для символов, не имеет значения, подписан ли или не подписан char на любой из используемых вами платформ и компиляторов.

16 голосов
/ 31 июля 2009

Вы что-то не так поняли. подписанный символ всегда подписан. неподписанный символ всегда без знака. Но то, является ли обычный символ подписанным или неподписанным, зависит от конкретной реализации - это зависит от вашего компилятора. Это отличается от типов int, которые все подписаны (int - это то же самое, что int со знаком, short - как short). Более интересным является то, что char, подписанный char и unsigned char рассматриваются как три различных типа с точки зрения перегрузки функций. Это означает, что вы можете иметь в одном модуле компиляции три перегрузки функций:

void overload(char);
void overload(signed char);
void overload(unsigned char);

Для типов int наоборот, вы не можете иметь

void overload(int);
void overload(signed int);

потому что int и подписанный int одно и то же.

3 голосов
/ 31 июля 2009

Правильнее будет сказать, что это зависит от компилятора, и вы не должны рассчитывать на то, что char будет подписано или не подписано при использовании char без квалификатора signed или unsigned.

В противном случае вы столкнулись бы со следующей проблемой: вы пишете и отлаживаете программу, предполагая, что char подписано по умолчанию, а затем перекомпилируется с компилятором, предполагая иначе, и поведение программы резко меняется. Если вы полагаетесь на это предположение лишь время от времени в своем коде, вы рискуете столкнуться с непреднамеренным поведением в некоторых случаях, которые запускаются в вашей программе только при определенных условиях и которые очень трудно обнаружить и отладить.

2 голосов
/ 31 июля 2009

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

Типы символов в C и C ++

0 голосов
/ 31 июля 2009

знаковый символ всегда 8-битный и всегда имеет бит со знаком как последний бит.

беззнаковый символ всегда 8-битный и не имеет знакового бита.

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

0 голосов
/ 31 июля 2009

Наличие знака со знаком - скорее случайность того, как все базовые типы переменных обрабатываются в C, как правило, не полезно иметь отрицательные символы.

...