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 должен быть предпочтительнее в качестве типа элемента для широких символьных строк.