eggbertx
eggbertx

Reputation: 513

Using typedef as a shortcut for unsigned types in C

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

Answers (3)

chux
chux

Reputation: 153457

The overall idea is reasonable - write portable code. OP's approach is not.

  1. __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.

  2. 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;.

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

Brandon83
Brandon83

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

giusti
giusti

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

Related Questions