Home NewsBlog Projects Contact
E.X.P.L.O.R. in development now! Cool Developer Stuff

Clever Code

countof operator

In C++ the sizeof operator is pretty handy. It is also useful to know the size of an array. The countof operator is useful for that, here’s how you define it:

#define countof(a) (sizeof(array) / sizeof(0[(array)]))

And an example of how it could be used:

SomeStruct myStruct[] = { {value1,value2} , {value1_1,value2_1} };

for( int i=0; i<countof(myStruct); i++ )
{
myStruct[i].TheValueA = SomeNewValue;
}

Make Pointer Relative

Serializing pointers can be a difficult prospect. The following code can make a pointer relative to itself! Which can then be serialized. During de-serialization the pointer can then be made absolute. So long as the pointer and what it points to are still relative to each other inside the same block (even if that block is now in a different location) the pointer will point at the correct location.

///////////////////////////////////////////////////////////////////////////////
//!
// This function takes the address of a pointer and converts it contents to
// an absolute pointer.
// This is used to relocate data, the most common example is for a tool to
// create data that includes pointers that are correct for the current location
// in the tool memory, then to use pointer_make_relative to convert all pointers
// to relative values. Later, a different application, often on a different
// platform, will load the data and use pointer_make_absolute to correctly reset
// the pointers in their new location.
// @note neither this function nor pointer_make_relative has any effect on null
// pointers, they always remain null, as you would expect.
// @see pointer_make_relative
//
///////////////////////////////////////////////////////////////////////////////

inline void pointer_make_absolute( const void** p ) {

//don’t do anything for actual null pointers
if( *p == null ) {
return;
}

//make the non-null pointer absolute
//note: do _not_ change this code unless you really know what you’re doing!!!
// this code will ensure that relative target pointers are stored in
// target endian and absolute target pointers are stored in host endian.
// the difference in the code below between *p and *(intptr_t*)p is that
// vcc will not endian swap target pointers for *p but it will endian swap
// target integer values for *(intptr_t*)p.
*p = (const void**) ( (*(intptr_t*)p) - 1 + ((intptr_t)p) );
}


///////////////////////////////////////////////////////////////////////////////
//!
// This function takes the address of a pointer and converts it contents to
// a relative pointer.
// This is used to relocate data, the most common example is for a tool to
// create data that includes pointers that are correct for the current location
// in the tool memory, then to use pointer_make_relative to convert all pointers
// to relative values. Later, a different application, often on a different
// platform, will load the data and use pointer_make_absolute to correctly reset
// the pointers in their new location.
// @note neither this function nor pointer_make_absolute has any effect on null
// pointers, they always remain null, as you would expect.
// @see pointer_make_absolute
//
///////////////////////////////////////////////////////////////////////////////

inline void pointer_make_relative( const void** p ) {

//don’t do anything for actual null pointers
if( *p == null ) {
return;
}

//make the non-null pointer relative
//note: do _not_ change this code unless you really know what you’re doing!!!
// this code will ensure that relative target pointers are stored in
// target endian and absolute target pointers are stored in host endian.
// the difference in the code below between *p and *(intptr_t*)p is that
// vcc will not endian swap target pointers for *p but it will endian swap
// target integer values for *(intptr_t*)p.
*(intptr_t*)p = ((intptr_t)*p) + 1 - ((intptr_t)p);
}