ReignBough
ReignBough

Reputation: 51

Pointer to two different structures

I have three structures header, dataA, and dataB. The header will determine the structure that will be used. The dataA and dataB have almost the same structure (let's say):

struct dataA
{
    int   intValue;
    char  reserved1[8];
    float floatValue;
    char  reserved2[4];
    short shortValue;
};

struct dataA
{
    int   intValue;
    short shortValue;
    char  reserved[2];
    float floatValue;
};

I want to print it like:

sprintf(outStr, "%i, %f, %s", p->intValue, p->floatValue, p->shortValue);

-- OR --

sprintf(outStr, "%i, %f, %s", p.intValue, p.floatValue, p.shortValue);

How do I declare p? (NOTE: Both dataA and dataB have a large structure but almost the same data, except for those that are reserved values.)

I am thinking something like this:

void * p;

if (header->type==1)
   p = (dataA*)(pData);
else if (header->type==2)
   p = (dataB*)(pData);

// print all data here

NOTE: The pData here is a pointer to a (raw) data that I will be read. I only need those non-reserved values and disregard the reserved values.

Upvotes: 2

Views: 164

Answers (1)

James McNellis
James McNellis

Reputation: 355019

Move the printing logic into a function template:

template <typename T>
int print_data(char* const str, std::size_t const len, T const* const p)
{
    return std::snprintf(
        str, len,
        "%i, %f, %s",
        p->intValue, p->floatValue, p->shortValue);
}

Then call this function from your switching logic:

if (header->type==1)
    print_data(str, len, static_cast<dataA const*>(pData));
else if (header->type==2)
    print_data(str, len, static_cast<dataB const*>(pData));

If you plan on using std::snprintf, it would be a good idea to add static_asserts to the print_data function template to ensure that the types of the data members of T are the types that you expect, just to be sure.

Note that if your platform has strict alignment requirements and the data pointed to by pData is not guaranteed to be correctly aligned for all of your target types, you will need to replace the cast with a copy of bytes into a suitably aligned buffer.

Upvotes: 7

Related Questions