2

I am reading Game Engine Architecture by Jason Gregory, and I am confused by a sentence in the book:

"...most game egines achieve source code portability by defining their own custom atomic data types. For example, at Naughty Dog we use the follow atomic data types:

*F32 is a 32-bit IEEE-754 floating-point value

*U8, I8, U16, I16, U32, I32, U64 and I64 are unsigned and signed 8-, 16, 32, and 64-bit integers, respectively..."

I have looked all over google and the web trying to find a way to define these kinda of data types. Is this usually done by just using #define directives to assign these values to whatever the value is, like this:

#define U8 __int8 ect..

If there is any link, book or advice anyone can offer to understand what he means by this, or how to set it up, I would appreciate it.

1 Answers1

2

Using #define is definitively not a good idea in C++. Even in C, you can use typedef for types.

typedef unsigned __int8  U8;

However, as mentioned by Dave (see his link for complete list), you have atomic definitions in C++ such as:

std::atomic_uint_fast8_t
// or
std::atomic<std::uint_fast8_t>
// with the typedef:
typedef std::atomic_uint_fast8_t  U8;

Yet, if you want to be a little less advanced, you can include the cstdint include, which is in most cases what will work on most computers:

#include <cstdint>

That gives you the standard [u]int[8,16,32,64]_t types. So the same type as above would be:

uint8_t my_var;
// if you really want to use a typedef:
typedef uint8_t U8;
U8 my_var;

These types are portable, without the need for an extra typedef.

For float and double, these are generally portable. What is not is the long double which is rarely used anyway. You could still have a typedef, just in case:

typedef float F32;

Then anywhere in your code, you MUST use those definitions and not the default C/C++ types (i.e.char, short, int, long are forbidden.)

Put all of those in a header that all the other C++ files include.


Update:

enough memory in each type

Obviously, if you use uint8_t, then you can be sure that you at least have an 8 bit number. It could be 16 bits too... (some processors are limited that way) Similarly, a uin32_t will have at least 32 bits.

It is possible to have a compile time check if you really want to make sure. That makes use of the sizeof() with a template. See here:

Compile-time sizeof conditional

Note that this is not specific to games. Any programming should careful choose their variable types. More and more people are making use of 64 bit integers to make sure they can support sizes over 2Gb (4Gb if you though of using an unsigned...)

FYI -- one of the European Ariane rockets (it was French at the time of the accident) was blown up because a variable was 8 bits when it should have been 16 bits. That gives you an idea why it's important...

Community
  • 1
  • 1
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • In the book, he seems to make it out to be important to make sure that you always have the right amount of memory in each data type. I guess if the standard types are enough, I just don't understand why he would make a point to mention making them yourself. – Maxwell Miller Jan 08 '15 at 02:44
  • @max because such types (`uint8_t` etc) did not always exist. Nor did `atomic`. And if you have to use different threading platforms on different architectures, you will want a common wrapper. – Yakk - Adam Nevraumont Jan 08 '15 at 03:34
  • Yes, Yakk is right. If you had to program on an old console, you may be bugged down to only an older version of gcc, like 3.x or something, or much worse, VC6... In that case, having one header that defines all your own U8, U16, etc. would save you a lot of time. – Alexis Wilke Jan 08 '15 at 10:12