В книге "Полная ссылка на C" упоминается, что char
по умолчанию не подписан.
Но я пытаюсь проверить это с помощью GCC, а также Visual Studio. Он принимает его как подписанный по умолчанию.
Который правильный?
В книге "Полная ссылка на 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 C Dennis Ritchie, которая является стандартной базой для ANSI C, простые символы, подписанные или неподписанные, зависят от машины, но печатные символы всегда положительны.
В соответствии со стандартом C подпись прозрачности char определяется "реализацией".
В целом разработчики выбрали то, что было более эффективным для реализации на их архитектуре. В системах x86 char обычно подписывается. На консольных системах он обычно не подпадает под действие (Apple iOS является исключением).
В соответствии с "языком программирования С++" Бьярном Страуступом, 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
. Но я не уверен, что это всегда безопасно для других случаев.