Do you prefer to see something like t_byte*
(with typedef unsigned char t_byte
) or unsigned char*
in code?
I\'m leaning towards
I suggest that if your compiler supports it use the C99 <stdint.h>
header types such as uint8_t
and int8_t
.
If your compiler does not support it, create one. Here's an example for VC++, older versions of which do not have stdint.h
. GCC does support stdint.h
, and indeed most of C99
One problem with your suggestion is that the sign of char
is implementation defined, so if you do create a type alias. you should at least be explicit about the sign. There is some merit in the idea since in C# for example a char
is 16bit. But it has a byte type as well.
Additional note...
There was no problem with your suggestion, you did in fact specify unsigned.
I would also suggest that plain char
is used if the data is in fact character data, i.e. is a representation of plain text such as you might display on a console. This will present fewer type agreement problems when using standard and third-party libraries. If on the other hand the data represents a non-character entity such as a bitmap, or if it is numeric 'small integer' data upon which you might perform arithmetic manipulation, or data that you will perform logical operations on, then one of the stdint.h
types (or even a type defined from one of them) should be used.
I recently got caught out on a TI C54xx compiler where char
is in fact 16bit, so that is why using stdint.h where possible, even if you use it to then define a byte
type is preferable to assuming that unsigned char
is a suitable alias.
I prefer for types to convey the meaning of the values stored in it. If I need a type describing a byte as it is on my machine, I very much prefer byte_t
over unsigned char
, which could mean just about anything. (I have been working in a code base that used either signed char
or unsigned char
to store UTF-8 strings.) The same goes for uint8_t
. It could just be used as that: an 8bit unsigned integer.
With byte_t
(as with any other aptly named type), there rarely ever is a need to look up what it is defined to (and if so, a good editor will take 3secs to look it up for you; maybe 10secs, if the code base is huge), and just by looking at it it's clear what's stored in objects of that type.
Personally I prefer boost::int8_t
and boost::uint8_t
.
If you don't want to use boost you could borrow boost\cstdint.hpp
.
Another option is to use portable version of stdint.h (link from this answer).
I prefer to use standard types, unsigned char, uint8_t, etc., so any programmer looking at the source does not have to refer back to headers to grok the code. The more typedefs you use the more time it takes for others to get to know your typing conventions. For structures, absolutely use typedefs, but for primitives use them sparingly.
Besides your awkward naming convention, I think that might be okay. Keep in mind boost does this for you, to help with cross-platform-ability:
#include <boost/integer.hpp>
typedef boost::uint8_t byte_t;
Note that usually type's are suffixed with _t
, as in byte_t
.
If you're using C99 or newer, you should use stdint.h
for this. uint8_t
, in this case.
C++ didn't get this header until C++11, calling it cstdint
. Old versions of Visual C++ didn't let you use C99's stdint.h
in C++ code, but pretty much every other C++98 compiler did, so you may have that option even when using old compilers.
As with so many other things, Boost papers over this difference in boost/integer.hpp, providing things like uint8_t
if your compiler's standard C++ library doesn't.