views:

458

answers:

6

The title pretty much says it all, do you prefer to see something like t_byte* (where t_byte would be a typedef for unsigned char) or unsigned char* in code? I'm leaning towards t_byte in my own libraries, but have never worked on a large project where this approach was taken, and am wondering about pitfalls.

Regards, Dan O.

+11  A: 

If your compilers support the C99 extensions for both C and C++, you should use stdint.h for this. uint8_t, in this case.

Warren Young
+2  A: 

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).

Kirill V. Lyadvinsky
I'm not really sold on requiring a boost header just for typedefs.
Dan O
Note that while stdint.h is defined by C99, there is no <cstdint> required by the current ISO C++ standard (because it predates C99), so you may find in some compilers you have to use the C convention for header names is use stdint types, and that would be the most portable form.
Clifford
+1  A: 

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.

GMan
Types you define should NOT be suffixed with "_t" as such names are reserved for extensions to the language and standard libraries (e.g. so that adding uint8_t does not break lots of existing code).
Dipstick
@chrisharris where did you find this info? I am looking through a draft of the ISO C++ Standards and can't find that section, but I have a co-worker who likes to suffix all his class/function templates that way and would like to point it out to him.
+4  A: 

I suggest that if your compiler supports it use the C99 header types such as uint8_t and int8_t.

If your compiler does not support it, create one. Here's an example for VC++, which does not have . GCC does support , 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 is 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.

Clifford
Good point about my example, I marked Warren's answer correct because he was first and his post was succinct. Upvoted you at least...
Dan O
A: 

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.

Misk
A: 

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.

sbi