Подтвердить что ты не робот

Рекомендации: Должен ли я создать typedef для байта на C или С++?

Вы предпочитаете видеть что-то вроде t_byte*typedef unsigned char t_byte) или unsigned char* в коде?

Я склоняюсь к t_byte в своих собственных библиотеках, но никогда не работал над крупным проектом, где этот подход был взят, и мне интересно о подводных камнях.

4b9b3361

Ответ 1

Если вы используете C99 или новее, вы должны использовать stdint.h для этого. uint8_t, в этом случае.

С++ не получал этот заголовок до С++ 11, называя его cstdint. Старые версии Visual С++ не позволяли использовать C99 stdint.h в коде С++, но почти все другие компиляторы С++ 98, поэтому у вас может быть такая опция даже при использовании старых компиляторов.

Как и во многих других вещах, Boost документирует эту разницу в boost/integer.hpp, предоставляя такие вещи, как uint8_t, если нет стандартной библиотеки С++ для компилятора.

Ответ 2

Я предлагаю, чтобы, если ваш компилятор поддерживает его, используйте типы заголовков C99 <stdint.h>, такие как uint8_t и int8_t.

Если ваш компилятор не поддерживает его, создайте его. Вот пример для VС++, более старые версии которого не имеют stdint.h. GCC поддерживает stdint.h, и действительно, большинство C99

Одна из проблем с вашим предложением состоит в том, что знак char определяется реализацией, поэтому, если вы создаете псевдоним типа. вы должны хотя бы четко указать знак. В этой идее есть некоторые достоинства, поскольку в С#, например, char - 16 бит. Но он также имеет байтовый тип.


Дополнительная заметка...

Не было никаких проблем с вашим предложением, вы действительно указали unsigned.

Я бы также предположил, что обычный char используется, если данные фактически являются символьными данными, то есть представляет собой простой текст, например, который вы можете отображать на консоли. При использовании стандартных и сторонних библиотек это приведет к меньшему количеству проблем с согласованием типов. Если, с другой стороны, данные представляют собой несимвольный объект, такой как растровое изображение, или если это числовые "мелкие целые" данные, по которым вы можете выполнить арифметическую манипуляцию, или данные, на которые будут выполняться логические операции, тогда один из stdint.h должны использоваться типы (или даже тип, определенный из одного из них).

Недавно я попался на компилятор TI C54xx, где char на самом деле 16 бит, поэтому, когда это возможно, используйте stdint.h, даже если вы используете его, чтобы затем определить тип byte, предпочтителен предположить что unsigned char является подходящим псевдонимом.

Ответ 3

Я предпочитаю, чтобы типы передавали значение сохраненных в нем значений. Если мне нужен тип, описывающий байт, как на моей машине, я предпочитаю byte_t over unsigned char, что может означать что угодно. (Я работал в базе кода, которая использовала либо signed char, либо unsigned char для хранения строк UTF-8.) То же самое касается uint8_t. Его можно просто использовать как целое число без знака 8 бит.

С byte_t (как и с любым другим точно подобранным типом) редко возникает необходимость поиска того, на что он определен (и если это так, хороший редактор займет 3 секунды, чтобы найти его для вас; возможно, 10сек, если база кода огромна), и просто взглянув на нее, она очистит то, что хранится в объектах этого типа.

Ответ 4

Лично я предпочитаю boost::int8_t и boost::uint8_t.

Если вы не хотите использовать boost, вы можете взять boost\cstdint.hpp.

Другой вариант - использовать переносимую версию stdint.h (ссылка this ответ).

Ответ 5

Помимо вашего неловкого соглашения об именах, я думаю, что это может быть хорошо. Имейте в виду, что ускорение делает это для вас, чтобы помочь с кросс-платформенной способностью:

#include <boost/integer.hpp>

typedef boost::uint8_t byte_t;

Обратите внимание, что обычно тип имеет суффикс _t, как в byte_t.

Ответ 6

Я предпочитаю использовать стандартные типы, unsigned char, uint8_t и т.д., поэтому любой программист, смотрящий на источник, не должен ссылаться на заголовки, чтобы получить код. Чем больше typedefs вы используете, тем больше времени требуется для того, чтобы другие узнали ваши типизирующие соглашения. Для структур, абсолютно использовать typedefs, но для примитивов использовать их экономно.