Рекомендации: Должен ли я создать typedef для байта в C или C ++? - PullRequest
18 голосов
/ 11 сентября 2009

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

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

Ответы [ 6 ]

21 голосов
/ 11 сентября 2009

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

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

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

7 голосов
/ 11 сентября 2009

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

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

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


Дополнительные примечания ...

С вашим предложением не возникло проблем, вы на самом деле указали unsigned.

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

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

4 голосов
/ 11 сентября 2009

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

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

2 голосов
/ 11 сентября 2009

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

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

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

1 голос
/ 11 сентября 2009

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

#include <boost/integer.hpp>

typedef boost::uint8_t byte_t;

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

0 голосов
/ 11 сентября 2009

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

...