Является ли char подписанным или неподписанным по умолчанию?

В книге "Полная ссылка на C" упоминается, что char по умолчанию не подписан.

Но я пытаюсь проверить это с помощью GCC, а также Visual Studio. Он принимает его как подписанный по умолчанию.

Который правильный?

Ответ 1

Книга не права. Стандарт не определяет, является ли обычный char подписанным или неподписанным.

Фактически, стандарт определяет три различных типа: char, signed char и unsigned char. Если вы #include <limits.h>, а затем посмотрите на CHAR_MIN, вы сможете узнать, является ли обычный char signed или unsigned (если CHAR_MIN меньше 0 или равен 0), но даже тогда, три стандарта различаются в отношении стандарта.

Обратите внимание, что char особенный в этом смысле. Если вы объявляете переменную как int, это на 100% эквивалентно объявлению ее как signed int. Это всегда верно для всех компиляторов и архитектур.

Ответ 2

Как указывает Алок, стандарт оставляет это на усмотрение реализации.

Для gcc значение по умолчанию подписано, но вы можете изменить это с помощью -funsigned-char. примечание: для gcc в Android NDK по умолчанию используется без знака. Вы также можете явно запросить подписанные символы с помощью -fsigned-char.

В MSVC значение по умолчанию подписано, но вы можете изменить его с помощью /J.

Ответ 3

C99 N1256 черновик. 6.2.5/15 "Типы" имеет это сказать о подписанности типа char:

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

и в сноске:

CHAR_MIN, определенный в <limits.h>, будет иметь одно из значений 0 или SCHAR_MIN, и это можно использовать для различения двух параметров. Независимо от сделанного выбора char является отдельным типом от двух других и не совместим ни с одним из них.

Ответ 4

Согласно книге языка программирования C C Dennis Ritchie, которая является стандартной базой для ANSI C, простые символы, подписанные или неподписанные, зависят от машины, но печатные символы всегда положительны.

Ответ 5

В соответствии со стандартом C подпись прозрачности char определяется "реализацией".

В целом разработчики выбрали то, что было более эффективным для реализации на их архитектуре. В системах x86 char обычно подписывается. На консольных системах он обычно не подпадает под действие (Apple iOS является исключением).

Ответ 6

В соответствии с "языком программирования С++" Бьярном Страуступом, char - это "реализация определена". Это может быть signed char или unsigned char в зависимости от реализации. Вы можете проверить, подписан ли char или нет, используя std::numeric_limits<char>::is_signed.

Ответ 7

Теперь мы знаем, что стандарт оставляет это до реализации.

Но как проверить тип со signed или unsigned, например, char?

Я написал макрос для этого:

#define IS_UNSIGNED(t) ((t)~1 > 0)

и протестируйте его с помощью gcc, clang и cl. Но я не уверен, что это всегда безопасно для других случаев.