How to resolve typedef conflict in APIs?

Started by
11 comments, last by Khatharr 8 years, 5 months ago

I've started to integrate Valve's Steam API with our multiplayer game but have immediately run into problems of this sort:

steam\sdk\public\steam\steamtypes.h(44): error C2371: 'uint32' : redefinition; different basic types

since Steam defines types with the same naming scheme as the game engine. (neither utilize namespaces)

Example Steam: typedef unsigned __int32 uint32;

Example Engine: typedef unsigned long uint32

I'm unsure how to go about resolving this.

Anyone have a solution?

Thanks

Advertisement

The answer is that the engine's typedef is plain wrong (long is no way guaranteed to be 32 bit). Do you have any way of influencing that part? Is it your own engine or thrid party.

Add typedef inside a namespace :


namespace Engine
{
  // 8-bit size types.
  typedef int8_t Int8;
  typedef uint8_t UInt8;

  // 16-bit size types.
  typedef int16_t Int16;
  typedef uint16_t UInt16;

  // 32-bit size types.
  typedef int32_t Int32;
  typedef uint32_t UInt32;

  // 64-bit size types.
  typedef int64_t Int64;
  typedef uint64_t UInt64;

} // namespace Engine
Use namespaces, or dont ever include engine and 3rd party headers into the same CPP file -- use proper implementation-hiding and codebase segregation.

Why do you want your own typedefs anyway? There are standard library headers that do exactly that, in a safe way.

Btw, whoever downvoted me, could you please be so kind as to tell me what you thought was wrong with my post? Thanks!

It wasn't me but the problem appears to be that while the standard does not guarantee the size of an unsigned long (except it must be at least 4 chars), every known, modern compiler appears to stick to unsigned long = 4 chars.

Nevertheless I'm going to countervote back to zero since this really is an area where a reasonable explanation is needed in addition to the actual vote.

It wasn't me but the problem appears to be that while the standard does not guarantee the size of an unsigned long (except it must be at least 4 chars), every known, modern compiler appears to stick to unsigned long = 4 chars.

Before stdint.h, this kind of thing was common. You'd put it inside an #ifdef BLAH, with many #elif's for each compiler that you supported. E.g. You would know that if MSC_VER was a certain value, then int woulf be 32 bits.

According to the OP, the valve headers are doing something similar - using non-standard types that are custom to specific compilers (which meand their typedefs must also be insidr an #if PLATFORM block).

Why do you want your own typedefs anyway? There are standard library headers that do exactly that, in a safe way.

I have custom ones in my engine (in a namespace) because I like to write uint/u32/u64 rather than unsigned int/uint32_t/uint64_t :lol:

every known, modern compiler appears to stick to unsigned long = 4 chars.

That's not true. Most 64 bit compilers have sizeof(long) == 8...

Try this in basically every GCC or clang version on a 64 bit system:


int main() {
  printf("%zu\n", sizeof(long));
}

That's not true. Most 64 bit compilers have sizeof(long) == 8...

On 64bit windows compilers, the convention is that, long long and pointers are 64 bit, but int and long remain 32bit.

But theres also some wacky linux compilers where int, long and long long are all 64 bit :(
Linux has mostly settled on the convention that in remains 32bit, but long and long long are 64bit.
Apparently only on Linux x64, Windows x64 chose to go another way. I'm staying out of that though. When I had to have a particular size in the old days I always used Boost's sized integer types. Nowadays there is cstdint. Doing that by hand for more than the one compiler in front of you was always a quick route to madness...

This topic is closed to new replies.

Advertisement