Sign in to follow this  
Alessio1989

How do you deal with tons of different same fundamental data types?

Recommended Posts

Let us stay simple and state I want and need to use a single definition for fundamental types with fixed dimensions. (let's forget about why do Microsoft and the C/C++ standards provides non-fixed size...)

How do you deal with the tons of the Windows data types, the VC compiler data types, and the C/C++ unfixed data types? Do you split into two parts your project, one where you code only with your own defined types (where you do not have any external library includes) and another where you have to deal with the Windows headers or other libraries?

 

Actually I pretty like to use the cstding fixed-size integers, but every-time a function or a structure except a Windows data type I always check for compatibility through C++-style casts (not C-style casts). It is useless to state how boring and annoying is this.

I was thinking to create an header where using tons of static_assert and check the compatibility of my types with Windows Data types and C/C++ types. But I am not sure about that, since I was to add it in the PCH after the Windows and the C/C++ standard library includes.

 

So, any advice how to make neat all this is accepted.

Edited by Alessio1989

Share this post


Link to post
Share on other sites

I include <cstdints>, and use the standardized fixed width types: uint64_t, uint32_t, uint16_t, uint8_t, etc...

If your implementation doesn't support that type, then that type won't be defined, afaik.

 

Typically, I use int or unsigned for general usage, and size_t, uint32_t, etc... to more explicitly indicate my assumptions only when I need the fixed width.

 

Occasionally I have to talk to other 3rd party libraries that use other formats, and in those situations I try to isolate the additional formats only to the borders of where my code needs to talk to that library.

Share this post


Link to post
Share on other sites

What do you do in a piece of code where you retrieve/pass parameters to/from Windows libraries? Actually I pass my types (or just <cstint> types) and then I static_cast them from/to windows data types. But this is really annoying.

Edited by Alessio1989

Share this post


Link to post
Share on other sites

I don't deal with Win32 directly, but I do deal with some other third-party libraries with their own types (Qt, GL, and SFML for example).

 

In those cases, if it makes sense to do so, I do static_cast. That's the appropriate way to convert between two similar data types.

Yea, it can get slightly annoying, but in classes that deal excessively with a third-party library, sometimes it makes more sense to treat that class as an extension to that third-party library, and use that library's third-party types internally or even externally.

 

Every class basically falls into "My code" or "Extension of that library's code", so either my code only calls into that library in a few isolated places, or it calls into my class that wraps functionality and uses the types internally.

Share this post


Link to post
Share on other sites

Windows-specific code should always be strongly decoupled/isolated from the rest of your code-base. That's just good cross-platform practice!

Only very small amounts of your game should interact with Windows (or other low-level APIs) directly, and these parts of your game should be isolated behind some nice, easy-to-use interface. The rest of your game (99% of your code) should be all nice and standard and clean and portable :)

Share this post


Link to post
Share on other sites

Yes, I still try to separate my own code with code that directly interact with 3rd party libraries (like win32 APIs). I was wondering if there are some dirty tricks (even preprocessor tricks) to feed my laziness and avoid explicit static_cast et similia.

 

Another question: is a good practice to "undef" 3rd party data types in the project parts you do not need them? I saw that in the UE source code.

Edited by Alessio1989

Share this post


Link to post
Share on other sites

Another question: is a good practice to "undef" 3rd party data types in the project parts you do not need them? I saw that in the UE source code.

Don't include them in the other parts in the first place! IMHO having to attempt to undef stuff is a failing.
I've worked with quite a few engines that put "windows.h" into the PCH, which pollutes every single damn file... IMHO this is a terrible thing to do.
Keep implementations hidden smile.png

I was wondering if there are some dirty tricks (even preprocessor tricks) to feed my laziness and avoid explicit static_cast et similia.

You can make some shorthands...
MyVec4 cast( const TheirVec4& v )
{
  static_assert( sizeof(MyVec4) == sizeof(TheirVec4) );
  static_assert( offsetof(MyVec4,x) == offsetof(TheirVec4,x) );
  static_assert( offsetof(MyVec4,y) == offsetof(TheirVec4,y) );
  static_assert( offsetof(MyVec4,z) == offsetof(TheirVec4,z) );
  static_assert( offsetof(MyVec4,w) == offsetof(TheirVec4,w) );
  return *(MyVec4*)&v;
}
^^ It's good practice to always document any assumption that you make with an assertion or compile-time assertion. Here I'm documenting that it's safe to reinterpret cast these two vec4 types smile.png

As for the windows types, many of them are just typedefs, so there's no casting requried, e.g.
BYTE windows = 42;
uint8_t portable = windows;//no cast, because BYTE is an unsigned 8bit integer!
Edited by Hodgman

Share this post


Link to post
Share on other sites

Thank you, I was not aware about offsetof macro... So, I will try to create some sort of control checks where I put the Windows headers and since cl.exe do not allows multiple pre-compiled headers, I will split all the work into two projects (which was not the initial intention because I am actually working alone on it).

Edited by Alessio1989

Share this post


Link to post
Share on other sites


I will split all the work into two projects (which was not the initial intention because I am actually working alone on it).
Euhm, how is the number of projects related to the number of people working on it?

The normal reason to make a separate project is to handle code sharing between projects (eg you make a library that you want to use in other projects too), or due to licensing or code support reasons (maybe you make code for special device that not everybody has).

 

Secondly, why do you need two projects?

It's perfectly fine to include 3rd party header files into the .cpp file, possibly with declaring some classes in the header file to make the compiler happy.

In that way, the "pollution" of the 3rd party definition stays within a few .cpp files, instead of spreading to the entire project.

Share this post


Link to post
Share on other sites

 


I will split all the work into two projects (which was not the initial intention because I am actually working alone on it).
Euhm, how is the number of projects related to the number of people working on it?

The normal reason to make a separate project is to handle code sharing between projects (eg you make a library that you want to use in other projects too), or due to licensing or code support reasons (maybe you make code for special device that not everybody has).

 

Secondly, why do you need two projects?

It's perfectly fine to include 3rd party header files into the .cpp file, possibly with declaring some classes in the header file to make the compiler happy.

In that way, the "pollution" of the 3rd party definition stays within a few .cpp files, instead of spreading to the entire project.

 

 

Usually it's not related. But I am not working on a "huge" project, and I also like to keep things simple. I am also lazy and I do not like spending much time into VS project settings : p

 

Since I usually work with a laptop and since I usually need to stay in battery mode only, splitting into two project will allows me to include the winAPI headers into PCH where I need, this will speed up the compilation a lot and deny annoying accurate header-include-tree planning. Finally I really like to abuse the static analysis tools, so compilation time get more important than ever for me.

 

I know these are not good practice in general, but they should works for me.

Edited by Alessio1989

Share this post


Link to post
Share on other sites

I've worked with quite a few engines that put "windows.h" into the PCH, which pollutes every single damn file... IMHO this is a terrible thing to do.


QFT.

Rage fills me every time I see that happen.

Not only does it pollute the files, but then other team members end up _using_ the bullcrap that's in windows.h, and then when it comes time to port your game to another platform you end up having to rewrite goofy Windows functions for all your platforms (and accept any inefficiencies or the like imposed by trying to wrap a Windows interface around a non-Windows OS' primitives).

If you ever include windows.h from another project-public header, you done goofed. Edited by SeanMiddleditch

Share this post


Link to post
Share on other sites

wrapper api's for all 3rd party libs is what i usually end up doing.  its rare when you find a lib with an API so clean you couldn't greatly simplify it with a wrapper api.

 

an example, my wrapper API for directx 9 (PODs and procedural code):

 

http://www.gamedev.net/blog/1731/entry-2258674-the-z3d-api/

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this