Import structs as nested, anonymous structs in union using C++

531 views Asked by At

Please consider the following "unchangeable" declarations:

typedef struct T_MESSAGE
{
    unsigned int  uiTimestamp;
    unsigned char ucDataType;
    unsigned int  uiDataSize;
    unsigned char aucData[1024];
} TT_MESSAGE;

typedef struct T_SENSORDATA_HEADER
{
    unsigned char ucSensorType;
    unsigned char ucMountingPoint;
} TT_SENSORDATA_HEADER;

In case the message contains Sensor Data, the data is stored within the aucData array, always beginning with the Sensor Data Header. I would like to create a union or struct, which allows me to directly access all members of such a message, without having to use another variable name. I hope you understand what I want to do by looking at my previous attempts. I tried it like this:

union SensorDataMessage
{
    struct T_Message;

    struct
    {
        unsigned : 32;  // Skip uiTimestamp
        unsigned : 8;   // Skip ucDataType
        unsigned : 32;  // Skip uiDataSize

        struct T_SENSORDATA_HEADER;
    };
};

and this:

struct SensorDataOverlay
{
    unsigned : 32;  // Skip uiTimestamp
    unsigned : 8;   // Skip ucDataType
    unsigned : 32;  // Skip uiDataSize

    struct T_SENSORDATA_HEADER;
};

union SensorDataMessage
{
    struct T_Message;
    struct SensorDataOverlay;
};

But none of that is working. In the end, I would like to be able to write something like this:

int Evaluate(SensorDataMessage msg)
{
    unsigned char tmp = msg.ucDataType;
    unsigned char tmp2 = msg.ucSensorType;
    [...]
}

From here I learned that what I want to do should be possible, but only in Visual C:

A Microsoft C extension allows you to declare a structure variable within another structure without giving it a name. These nested structures are called anonymous structures. C++ does not allow anonymous structures.

You can access the members of an anonymous structure as if they were members in the containing structure.

However, this seems not to be entirely true, since anonymous structs can be used in Visual C++ as well, like it is suggested here.

I would highly appreciate any help.

1

There are 1 answers

0
Ju-Hsien Lai On

Here's what I found might help you out:

  1. Have to change C/C++ compiler as Compile as C code (/TC) to gain anonymous structure support.

enter image description here

  1. There's a missing keyword union on the declaration of Evaluate()

  2. Anonymous native data type declaration in SensorDataOverlay seems would confuse the compiler, so I try to collect them into one single structure as CommonHeader, and put one pack in SensorDataOverlay.

I found T_MESSAGE and SensorDataOverlay shared the same scheme in the first three fields, I would say it would be better to be replaced as CommonHeader, would make more sense in perspective of data inheritance. Since at the beginning of question you pointed out that the T_MESSAGE is unchangeable, so I don't do any modification in the following code.

the complete code posted here, able to run, and I guess the memory offset scheme meets your needs.


*struct CommonHeader
{
    unsigned int  skipUiTimestamp;
    unsigned char skipUcDataType;
    unsigned int  skipUiDataSize;
};

struct SensorDataOverlay
{
    /* Use CommonHeader instead */
    //unsigned : 32;  // Skip uiTimestamp
    //unsigned : 8;   // Skip ucDataType
    //unsigned : 32;  // Skip uiDataSize

    struct CommonHeader;
    struct T_SENSORDATA_HEADER;
};

union SensorDataMessage
{   
    TT_MESSAGE;
    struct SensorDataOverlay;
};

int Evaluate(union SensorDataMessage msg)
{
    unsigned char tmp = msg.uiDataSize;
    unsigned char tmp2 = msg.ucSensorType;

    return 0;
}*