PDA

View Full Version : Typecast of two structs



Markus_AC
4th October 2011, 12:56
I'm struggeling about with the typecast of one struct into another.

I want to do something like this:



struct myFirstStruct
{
unsigned char c1;
unsigned char c2;
unsigned char c3;
unsigned char c4;
unsigned char c5;
unsigned char carray1[6];
};

struct mySecondStruct
{
unsigned char carray1[4];
unsigned char c1;
unsigned char carray2[6];
};

...

myFirstStruct s1;
mySecondStruct s2;

s1 = (myFirstStruct)s2;


As you can see, both arrays are of equal size.

But I always get an error, that this conversion can't be done.
How can I do this?

nish
4th October 2011, 13:05
if your goal is to copy to data from s2 to s1, you can try memcpy(&s1,&s2,sizeof(s2));

Markus_AC
4th October 2011, 13:20
As I reviewed my exisitng sources I regocnized that my sample source-code was a little different. I have a myFirstStruct pointer and want to set this pointer to an existing pointer of mySecondStruct:



myFirstStruct *s1;
mySecondStruct *s2;

// fill s2 with some data

s1 = (myFirstStruct*)s2;

nish
4th October 2011, 14:31
As I reviewed my exisitng sources I regocnized that my sample source-code was a little different. I have a myFirstStruct pointer and want to set this pointer to an existing pointer of mySecondStruct:



myFirstStruct *s1;
mySecondStruct *s2;

// fill s2 with some data

s1 = (myFirstStruct*)s2;


this code compiles well and works for me. what is the error for you?

joseluis
4th October 2011, 14:42
As I reviewed my exisitng sources I regocnized that my sample source-code was a little different. I have a myFirstStruct pointer and want to set this pointer to an existing pointer of mySecondStruct:



myFirstStruct *s1;
mySecondStruct *s2;

// fill s2 with some data

s1 = (myFirstStruct*)s2;



Hi,

(myFirstStruct*) is the C way to cast. In C++ is the worst way to cast.
Take a look to dynamic_cast, static_cast, const_cast and even the devil reinterpret_cast (something you have to avoid)

Qt has it's own way to cast when you work with QObjects derivatives


In any case, the code is wrong

You are copying the pointers, not the data

And after s1 = (myFirstStruct*)s2; the previus value pointed by s1 is managed by no one, therefore a memory leak.

If you work with linux, take a look to valgrind

You have also be carefull with automatic copy constructor and automic assignament method

In this case, they are ok, but is better if you comment it explicity. Take a look to effective C++ from Scott Meyer


In this example, you have to write...

*s1 = *s2;


This question is not a Qt question, try to look a diferent forum for this kind of questions (sorry, I cannot recomend you anyone)

amleto
4th October 2011, 22:45
what you are trying to do is very bad anyway. You are basically just trying to get around type safety. And for no good reason - just getting from one byte buffer to another.

And you should be careful about presuming struct size just from eyeballing the class def - size changes depending on what padding etc has been needed/used.

ChrisW67
4th October 2011, 23:14
As you can see, both arrays are of equal size.

Actually, both structs might be the same size but that will depend on the way the compiler packs the structures: see Data Structure Alignment (http://en.wikipedia.org/wiki/Data_structure_alignment). You will probably get away with it most of the time if all the elements are chars. If you mix types then watch out:


#include <iostream>

struct myFirstStruct
{
unsigned char c1;
unsigned char c2;
unsigned char c3;
unsigned char c4;
unsigned char c5;
unsigned char carray1[6];
};

struct mySecondStruct
{
unsigned char carray1[4]; // 4*1 byte
unsigned char c1;
unsigned char carray2[6];
};

struct myThirdStruct
{
unsigned short sarray1[2]; // 2*2 bytes
unsigned char c1;
unsigned char carray2[6];
};

int main(int argc, char **argv)
{
std::cout << sizeof(unsigned char) << " " << sizeof(unsigned short) << std::endl;
std::cout << sizeof(myFirstStruct) << " " << sizeof(mySecondStruct) << " " << sizeof(myThirdStruct) << std::endl;
return 0;
}

outputs:


1 2
11 11 12

To do this cast safely requires an explicit copy constructor.