What is the purpose of specific api typedefs like GLsizei GLint GLvoid?

What is the purpose of specific api typedefs like GLsizei GLint GLvoid?

I see this everywhere in c and C ++ code. Base types are often typed with a library prefix / suffix. What are the reasons for this? Is this a good practice? Should my programs do something similar to themselves?

At first glance, the code seems a little less readable. You have to take a moment to translate GLint to int in your head, and this is a simple example.

Something like UINT does more, because for me, at least, it is an abbreviation of unsigned int in four lines.

+7
c ++ c typedef opengl
source share
3 answers

This is not about abbreviation of names, but about portability. For different platforms, you have to distinguish between these things in different ways.

In Std-C, long can be 32 or 64 bits, depending on your compiler / target, so you can not safely assume that this is a certain size. Thus, the author of the library types its own type, guaranteeing a certain size, with knowledge of the target platform.

eg.

 #ifdef _WIN32 typedef __int64 INT64; // long will not be 64 bit on Windows/VC. #elif __GNU_C__ typedef long INT64; // gcc typically uses 64 bit longs. #elif // ... other platforms ... ... #endif 

And if compilers change type properties in future versions, types can be edited in one place.

In the past, you also had a typical case where an int could be 16 or 32 bits in size, so you could not just use the raw int type in code where you need the DWORD size argument.

Therefore, you have things like LPARAM and WPARAM .

It is also used as a form of abstraction. This is why you see typedefs as

 typedef int Handle; 

Since while it is int , the author of the library reserves the opportunity to change it later on the track to something else, say, void * or any other type that they consider necessary.

But the client code does not have to know this int specifically, as this is exactly what it is now. All the client needs to know is to pass it along with functions that accept the Handle type.

Typedefs also allow you to configure at compile time. For example. some libraries may be of type Real for real numbers. It can be defined as

 #ifdef USE_DOUBLE_PREC typedef double Real; #else typedef float Real; #endif 

And the library user can optionally set /DUSE_DOUBLE_PREC when compiling to get double precision float support, but the important thing is that no library code should be changed for this, since it was abstracted.

+3
source share

For the most part, when a library defines base types without guaranteed properties for similarly named types in the standard (think INT , GLint , gint , LPSTR , u32 , u_int , etc.), the goal is this:

  • To β€œlabel” your code with a lot of library dependency, so it hurts you to reuse your code without a library or
  • Ignorance that the C standard provides appropriate types for the needs of the library.

Based on one of my favorite principles: β€œNever be angry, which can be adequately explained by stupidity,” you can go with No. 2, but it really depends on you.

Personally, whenever you code such an API, I throw away library types and use the correct natural types ( INT , char * , uint32_t , etc.) in their place. Then it’s easy to adapt my code for use without a library when I need it, and the code is more readable for people not familiar with the library.

+2
source share

This makes it possible to change the typedef in one place, and not to search and replace the entire code base, if it becomes necessary to change the base type. However, I also find him more β€œnoisy” than anything, and rarely saw him ever in a real-life scenario.

The only example that I have seen in a decent way is to swim if you work in games, and you may need to port your game to / from Nintendo DS, since DS initially works with fixed-point numbers. In this case, you have a special typedef for the float, so it is really superimposed on the float on most platforms and on the special fixed-point class on DS.

+1
source share

All Articles