Является ли char подписанным или беззнаковым по умолчанию?
Вопрос
В книге «Полный справочник C» упоминается, что char
по умолчанию является беззнаковым.
Но я пытаюсь проверить это с помощью GCC, а также Visual Studio.Он воспринимает это как подписано по умолчанию.
Какой из них правильный?
Решение
Книга неправильная.Стандарт не определяет, является ли простой char
подписан или не подписан.
Фактически стандарт определяет три различных типа: char
, signed char
, и unsigned char
.Если вы #include <limits.h>
а потом посмотри CHAR_MIN
, вы можете узнать, если это просто char
является signed
или unsigned
(если CHAR_MIN
меньше 0 или равно 0), но даже в этом случае различаются три типа что касается стандарта.
Обратите внимание, что char
в этом смысле особенный.Если вы объявите переменную как int
это на 100% эквивалентно объявлению его как signed int
.Это всегда верно для всех компиляторов и архитектур.
Другие советы
Как Алок отмечает, стандарт оставляет это на усмотрение реализации.
Для gcc по умолчанию подписано, но вы можете изменить это с помощью -funsigned-char
. примечание: для gcc в Android NDK значение по умолчанию — без знака.Вы также можете явно запросить подписанные символы с помощью -fsigned-char
.
В MSVC по умолчанию подписано, но вы можете изменить это с помощью /J
.
Проект C99 N1256 6.2.5/15 «Типы» говорят о знаковости типа. char
:
Реализация должна определить, что char имеет тот же диапазон, представление и поведение, что и знаковый char или беззнаковый char.
и в сноске:
CHAR_MIN
, определенный в<limits.h>
, будет иметь одно из значений0
илиSCHAR_MIN
, и это можно использовать для различения этих двух вариантов.Независимо от сделанного выбора,char
является отдельным типом от двух других и несовместим ни с одним из них.
Согласно книге Денниса Ритчи «Язык программирования C», которая является де-факто стандартной книгой для ANSI C, простые символы со знаком или без знака зависят от машины, но печатные символы всегда являются положительными.
Согласно стандарту C, подпись простого символа «определена реализацией».
Обычно разработчики выбирали то, что было более эффективно для реализации в их архитектуре.В системах x86 символ обычно подписывается.В системах Arm он обычно не имеет знака (исключением является Apple iOS).
Согласно книге Бьярна Страуструпа «Язык программирования C++», char
является «определенной реализацией».Может быть signed char
или unsigned char
в зависимости от реализации.Вы можете проверить, есть ли char
подписан или нет с помощью std::numeric_limits<char>::is_signed
.
Мы знаем, что стандарт оставляет это на усмотрение реализации.
Но как проверить тип signed
или unsigned
, такой как char
?
Я написал макрос для этого:
#define IS_UNSIGNED(t) ((t)~1 > 0)
и протестируйте его с помощью gcc
, clang
, и cl
.Но я не уверен, что это всегда безопасно для других случаев.