Int8_t vs char; Какой из них лучший?
Мой вопрос может вас смутить, я знаю, что оба являются разными типами (signed char
и char
), однако в моих правилах написания кода указывается использование int8_t
вместо char
.
Итак, я хочу знать, почему я должен использовать int8_t
вместо типа char
. Есть ли какие-либо рекомендации по использованию int8_t
?
Ответы
Ответ 1
Использование int8_t
отлично подходит для некоторых обстоятельств - особенно когда тип используется для вычислений, где требуется 8-битное значение с подписью. Расчеты с использованием данных строгого размера (например, определяемый внешними требованиями, чтобы быть точным 8 бит в результате] (я использовал уровни цвета пикселей в комментарии выше, но это действительно было бы uint8_t
, поскольку отрицательные цвета пикселей обычно не существуют - за исключением, возможно, в цветовом пространстве типа YUV),
Тип int8_t
НЕ должен использоваться в качестве замены char
для строк. Это может привести к ошибкам компилятора (или предупреждениям, но мы действительно не хотим иметь дело с предупреждениями от компилятора). Например:
int8_t *x = "Hello, World!\n";
printf(x);
может хорошо компилироваться в компиляторе A, но давать ошибки или предупреждения для смешивания значений знака и без знака char в компиляторе B. Или если int8_t
даже не использует тип char
. Это точно так же, как ожидать
int *ptr = "Foo";
для компиляции в современном компиляторе...
Другими словами, int8_t
ДОЛЖНО использоваться вместо char
, если вы используете 8-битные данные для какуляции. Неверно оптовой заменять все char
на int8_t
, так как они далеки от того, чтобы быть одинаковыми.
Если есть необходимость использовать char
для строки/текста/etc, и по какой-либо причине char
слишком неопределенна (она может быть подписана или без знака и т.д.), тогда usign typedef char mychar;
или что-то в этом роде должен быть использован. (Вероятно, можно найти лучшее имя, чем mychar
!)
Изменить: я должен указать, согласны ли вы с этим или нет, я думаю, было бы довольно глупо просто подойти к тому, кто отвечает за этот "принцип" в компании, указать на должность на SO и "Я думаю, вы ошибаетесь". Попытайтесь понять, что такое мотивация. Там может быть больше, чем кажется на первый взгляд.
Ответ 2
Они просто делают разные гарантии:
char
гарантируется, что оно должно быть шириной не менее 8 бит и иметь возможность представлять либо все целые числа от -127 до 127 включительно (если они подписаны), либо между 0 и 255 (если не указано).
int8_t
не гарантируется существование (и да, есть платформы, на которых он не работает), но если он существует, он гарантирован 8-битным двоичным дополнением со знаком целого типа без битов заполнения; таким образом, он способен представлять все целые числа от -128 до 127, и ничего больше.
Когда вы должны использовать это? Когда гарантии, сделанные по типу, соответствуют вашим требованиям. Стоит отметить, однако, что для больших частей стандартной библиотеки требуются аргументы char *
, поэтому избегать char
полностью кажется близоруким, если только не преднамеренное решение не использовать эти библиотечные функции.
Ответ 3
int8_t
только подходит для кода, для которого требуется целочисленный тип со знаком точно 8 бит и не должен компилироваться, если такого типа нет. Такие требования намного реже, чем количество вопросов о int8_t
, и это указывают братья. Большинство требований к размерам состоит в том, что тип имеет не менее определенное количество бит. signed char
работает отлично, если вам нужно не менее 8 бит; int_least8_t
также работает.
Ответ 4
int8_t
задается стандартом C99 шириной всего в восемь бит и вписывается в другие типы гарантированной ширины C99. Вы должны использовать его в новом коде, где требуется точно 8-битное целое число со знаком. (Посмотрите также на int_least8_t
и int_fast8_t
.)
char
по-прежнему является предпочтительным в качестве типа элемента для однобайтовых символьных строк, так же как wchar_t
должен быть предпочтительнее в качестве типа элемента для широких символьных строк.