This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Driver' opaque pointer implementation

Other Parts Discussed in Thread: CONTROLSUITE

Hi folks

Looking at the opaque pointer implementation used in the C2000 drivers from the device support files there is the following pattern used in the header files:

typedef struct _FOO_Obj_ {    // Example class struct 
    uint16_t x;    // Example member
} FOO_Obj;

typedef struct FOO_Obj * FOO_Handle;

But FOO_Obj is a tag for a struct, using struct again in the pointer typedef seems incorrect... I would have thought it should be either typedef FOO_Obj * FOO_Handler; or typedef struct _FOO_Obj_ * FOO_Handler;. What is being achieved here with the current method?

Then in the driver source file there is the following pattern for use of a passed FOO_Handle:

FOO_Handle FOO_init(void *pmemory, const size_t numBytes)
{
    FOO_Handle fooHandle;
    fooHandle = (FOO_Handle)pMemory;
    return(fooHandle);
}

What is actually in fooHandle after the assignment? E.G. If I declare something to be of type FOO_Obj and then attempt to return the address (using return(&someFOO_Obj);) of it in a similar function that is supposed to return FOO_Handle, there is an error that the types do not match... so is FOO_Handle a pointer to _FOO_Obj_ or not?

Thanks

EDIT: Also, is hiding "pointer-ness" with a typedef not code smell? especially if wanting to pass as an argument with const-ness?

  • I agree with you. The current Handle definitions really don't make much sense. I believe they should be

    typedef struct _FOO_Obj_ *FOO_Handle;

    I've filed a bug to see that this gets corrected in controlSUITE.

    Thanks,
    Whitney

  • Hi Whitney,

    Looking into this aa bit more, I believe what the intention is here is a bit obscured by the use of similar struct and tag names, but basically the typedef struct FOO_Obj * FOO_Handle; creates a pointer to an incomplete struct, where the struct is named FOO_Obj.

    The FOO_Obj here is not the same as the tag name FOO_Obj from the typdef'd struct, as that is just a tag name. It just happens to be the same string (this is what had me confused).

    Thus the driver user may use the FOO_Handle as a pointer, but not access the members using the structure dreference operator (->) as the type (struct FOO_Obj) is still incomplete.

    It is then only inside the driver functions that the handle pointer is cast to a pointer to the essentially completely different _FOO_Obj_.

    I will add however that identifiers that begin with a leading underscore followed by an uppercase letter (or another underscore) are reserved at file-scope for use by the implementation, see Section 7.1.3 of the C standard (ISO 9899:1999) , meaning that the _FOO_Obj_ identifier is non-standard and potentially non-portable.