简体   繁体   中英

type-casting abstract class type to struct type with a integer member

I am studing Blender's GHOST code and found the following statement in GHOST_CreateSystem C-API function

  GHOST_ISystem::createSystem();
  GHOST_ISystem *system = GHOST_ISystem::getSystem();

  return (GHOST_SystemHandle)system;

GHOST_ISystem is an abstract class for a specific operating system such as win32, linux.

GHOST_SystemHandle is defined as structure type as follows:

typedef struct GHOST_SystemHandle__ {
      int unused; 
    } * GHOST_SystemHandle

I am not familiar with this kind of practice type-casting a pointer to class into a pointer to struct type with an integer member.

It would be appreciated to enlighten me the background about it.

Abstract class CANNOT be instantiated, to wit it cannot be converted. What happens here is a conversion of pointer values.

The calls GHOST_ISystem::createSystem(); and GHOST_ISystem::getSystem(); are calls to static functions. The latter returns a pointer to GHOST_ISystem . Pointer is a separate compound type and pointer to any declared type may materialized. A pointer to an abstract class-type can hold value of pointer to any derived type. GHOST_ISystem* is its static type while its dynamic type can vary.

The C-style cast syntax (GHOST_SystemHandle)system; is considered faux pas in C++ as it is too permitting, unsafe conversion. In this particular case it is treated as reinterpret_cast to a pointer GHOST_SystemHandle__ * .

The content of pointer system is bytewise copied to an instance of GHOST_SystemHandle , which is also a pointer. This would be hinged on assumption that all pointers in implementation have similar content and same size and that access by dereferencing the result would be legal.

Likely, the underlying reason was that derived types would have an integer field or an subobject with same alignment. Strictly speaking, result is unspecified . Memory model of original class and GHOST_SystemHandle__ should match. This assumes too many things:

  1. The abstract base class-type have no non-static member variable or it contains an equivalent member variable.
  2. The implementation is conforming to late-enough standard to ensure that base type subobject got zero size, if it doesn't have non-static member variables.
  3. The alignment requirement of derived type in question is same as alignment requirement of GHOST_SystemHandle__ . It it's not, result of *system->unused is undefined.

There is a number of ways it could be avoided in C++ and none was used, which suggests that code was converted from C without much of refactoring done while keeping interface type formats same for compatibility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM