Reputation: 513
I'm writing a Chip-8 emulator in C, and my goal is to have it be compatible with as many different operating systems, new and old as possible I realize that a lot of different types for representing exact bit widths have been added over the years, so is something like this reasonable to both create a shortcut (so I don't have to write lots of unsigned chars/longs) and account for compilers that already have the numbers defined? If not, is there a better/more efficient way to do this?
#ifdef __uint8_t_defined
typedef uint8_t uchar;
typedef int8_t schar;
typedef uint16_t ushort;
typedef int16_t sshort;
#else
typedef unsigned char uchar;
typedef signed char schar;
typedef unsigned short ushort;
typedef signed short sshort;
#endif
Upvotes: 2
Views: 3248
Reputation: 153457
The overall idea is reasonable - write portable code. OP's approach is not.
__uint8_t
is not defined by the C spec. Using that to steer compilation for portable code can lead to unspecified behavior. Better to use ..._MAX
definitions.
Code is creating types based on fixed width types on one platform and non-specified widths on another. Not a good plan. Where code needs fixed width types, use fixed width types like uint8_t
, etc. Where code wants to use short-hand uchar
for unsigned char
, etc., use a #define uchar unsigned char
or better typedef unsigned char uchar;
.
Attempting to create portable integer code without <stdint.h>
is folly. Even compilers that do not natively have the file have on-line look alikes easily findable.
If user still wants to create uchar
and friends like originally posted, suggest the more portable:
#include <stdint.h>
#ifdef INT_LEAST8_MAX
typedef uint_least8_t uchar;
#else
typedef unsigned char uchar;
#endif
#ifdef INT_LEAST16_MAX
typedef uint_least16_t ushort;
...
Upvotes: 1
Reputation: 206
Yes, this is a very good idea! Never assume sizes for primitive types. If you are writing portable code this is a must for maintainability! This little trick will save tons of time and will help create a good foundation for maintaining a portable code base.
Upvotes: 3
Reputation: 3538
You shouldn't make any assumptions on the sizes of the primitive types. Not even that char
has 8 bits. Check this discussion:
What does the C++ standard state the size of int, long type to be?
I think standard integer types are pretty well-supported. If you don't have stdint.h
, then your chances of cross-compatibility seem very dim to me. Expecting stdint.h
to be available for the compiler seems like a reasonable pre-condition.
Upvotes: 2