Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > redefining, and casting pointers to, structs

Reply
Thread Tools

redefining, and casting pointers to, structs

 
 
goldfita@signalsguru.net
Guest
Posts: n/a
 
      01-03-2006
I saw some code that appeared to do something similar to this

struct foo {
char offset[XXX];
int d;
};

struct foo {
int a;
int b;
char c;
int d; //same as other d
};

And the structs are defined differently in different files. I tried
doing this myself by just casting pointers to these structs from one
type to the other. I want the members after offset to align, so I
tried setting XXX = sizeof(int)*2+sizeof(char). But the compiler
padded that char with 3 more bytes; so, obviously it didn't work. Then
I tried embedding a struct defined as

struct inner_foo {
int a;
int b;
char c;
};

And I used that inside foo. Then I set XXX to sizeof(inner_foo). And
that worked. So my question is, is that safe and portable? If no,
please make a suggestion. Also, does the compiler always layout the
struct members in the same order you declare them?

thank you

-Todd

 
Reply With Quote
 
 
 
 
Mark McIntyre
Guest
Posts: n/a
 
      01-04-2006
On 3 Jan 2006 15:25:46 -0800, in comp.lang.c ,
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>I saw some code that appeared to do something similar to this
>
>struct foo {
> char offset[XXX];
> int d;
>};
>
>struct foo {
> int a;
> int b;
> char c;
> int d; //same as other d
>};
>

....
>So my question is, is that safe and portable?


No. The width of types varies from system to system and the compiler
is allowed to add padding between objects in a struct. It could pad
around your inner_foo differently on different implementations.

>If no, please make a suggestion.


I'm not sure why one would do this - if you have a definition of foo
why not use it?

>Also, does the compiler always layout the
>struct members in the same order you declare them?


Yes, but not necessarily all snuggled up together.
Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
 
Reply With Quote
 
 
 
 
Flash Gordon
Guest
Posts: n/a
 
      01-04-2006
(E-Mail Removed) wrote:
> I saw some code that appeared to do something similar to this
>
> struct foo {
> char offset[XXX];
> int d;
> };
>
> struct foo {
> int a;
> int b;
> char c;
> int d; //same as other d
> };
>
> And the structs are defined differently in different files.


Either you are misreading the code or the code is at *best* highly
platform specific and at worst completely broken.

> I tried
> doing this myself by just casting pointers to these structs from one
> type to the other. I want the members after offset to align, so I
> tried setting XXX = sizeof(int)*2+sizeof(char). But the compiler
> padded that char with 3 more bytes; so, obviously it didn't work.


As, indeed, it is allowed to. The compiler can insert padding after any
member of a struct for any reason.

> Then
> I tried embedding a struct defined as
>
> struct inner_foo {
> int a;
> int b;
> char c;
> };
>
> And I used that inside foo. Then I set XXX to sizeof(inner_foo). And
> that worked. So my question is, is that safe and portable?


No. The compiler could choose to place padding after struct inner_foo.
See comment above.

> If no,
> please make a suggestion.


I suggest not doing it.

> Also, does the compiler always layout the
> struct members in the same order you declare them?


Yes.

If you tell us what problem you are trying to solve, together with the
code you have written (cut down to a sensible size but still complete
and compilable), we might then be able to suggest alternative approaches.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
goldfita@signalsguru.net
Guest
Posts: n/a
 
      01-04-2006

> >If no, please make a suggestion.

>
> I'm not sure why one would do this - if you have a definition of foo
> why not use it?



I think the reason is because you may not have a definition. Suppose
you pass a pointer around to code that does not care what's in offset.
That code would only need to access member d. It may be receiving
pointers to structs of various definitions that it does not know about.
Nor could it konw if the definition can change.

-Todd

 
Reply With Quote
 
goldfita@signalsguru.net
Guest
Posts: n/a
 
      01-04-2006

> If you tell us what problem you are trying to solve, together with the
> code you have written (cut down to a sensible size but still complete
> and compilable), we might then be able to suggest alternative approaches.



I'm just trying to understand some code I've seen in the past and why
you might want to do it that way. There isn't really a problem. But
thanks anyway.

 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      01-04-2006
(E-Mail Removed) wrote:

Please leave the attribution in so we can see who said what.
Attributions being the lines like the above saying things like, "fred
wrote".

>>> If no, please make a suggestion.

>> I'm not sure why one would do this - if you have a definition of foo
>> why not use it?

>
> I think the reason is because you may not have a definition. Suppose
> you pass a pointer around to code that does not care what's in offset.
> That code would only need to access member d. It may be receiving
> pointers to structs of various definitions that it does not know about.
> Nor could it konw if the definition can change.


If you are doing that, then there is a special dispensation for the
*initial* members of a struct when they appear in a union. I.e.

struct foo {
int type;
char name[NAME_SIZE];
double val;
};

struct bar {
int type;
char name[NAME_SIZE];
int val;
}

union foobar {
struct foo foomess;
struct bar barmess;
}

In the above, you are allowed to use either foo or bar to access the
type and name fields, but from val on you have to use the correct struct
type. So for the type of thing you are discussing the correct method is
to put the common elements at the start of the struct and the elements
that vary at the end. It may simplify getting it right to put all the
initial members in to a struct and doing something like:

struct head {
int type;
char name[NAME_SIZE];
};

struct foo {
struct head messhead;
double val;
};

struct bar {
struct head messhead;
int val;
};

This also avoids the technical requirement to have the structs in a
union because you are allowed to convert a pointer to a struct to a
pointer to its first element, which is now itself a struct containing
all of the common elements. This is how I am generally inclined to do it.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
goldfita@signalsguru.net
Guest
Posts: n/a
 
      01-04-2006

Flash Gordon wrote:
> If you are doing that, then there is a special dispensation for the
> *initial* members of a struct when they appear in a union. I.e.
>
> struct foo {
> int type;
> char name[NAME_SIZE];
> double val;
> };
>
> struct bar {
> int type;
> char name[NAME_SIZE];
> int val;
> }
>
> union foobar {
> struct foo foomess;
> struct bar barmess;
> }
>
> In the above, you are allowed to use either foo or bar to access the
> type and name fields, but from val on you have to use the correct struct
> type. So for the type of thing you are discussing the correct method is
> to put the common elements at the start of the struct and the elements
> that vary at the end. It may simplify getting it right to put all the
> initial members in to a struct and doing something like:


Yes, it seems to make more sense in this example to put the common
members first. I'm confused about this union example though. (I've
never used one.) Are you saying the compiler will ensure the top
members of foo and bar that are the same will be aligned? Does that
mean the compiler has to be able to see the definitions to make the
union? What if foo and bar were declared elsewhere (with different
compiler options or on different compilers)?

-Todd

 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      01-04-2006
(E-Mail Removed) wrote:
> Flash Gordon wrote:
>> If you are doing that, then there is a special dispensation for the
>> *initial* members of a struct when they appear in a union. I.e.
>>
>> struct foo {
>> int type;
>> char name[NAME_SIZE];
>> double val;
>> };
>>
>> struct bar {
>> int type;
>> char name[NAME_SIZE];
>> int val;
>> }
>>
>> union foobar {
>> struct foo foomess;
>> struct bar barmess;
>> }
>>
>> In the above, you are allowed to use either foo or bar to access the
>> type and name fields, but from val on you have to use the correct struct
>> type. So for the type of thing you are discussing the correct method is
>> to put the common elements at the start of the struct and the elements
>> that vary at the end. It may simplify getting it right to put all the
>> initial members in to a struct and doing something like:

>
> Yes, it seems to make more sense in this example to put the common
> members first. I'm confused about this union example though. (I've
> never used one.) Are you saying the compiler will ensure the top
> members of foo and bar that are the same will be aligned?


Yes.

> Does that
> mean the compiler has to be able to see the definitions to make the
> union?


Of course. That's a bit like asking if a builder needs access to the
bricks to build a brick wall.

> What if foo and bar were declared elsewhere (with different
> compiler options or on different compilers)?


If you change compiler options (or compiler) for different translation
units then potentially all bets are off. After all, some compilers have
options specifically to change how things will be aligned.

Also, from the way you are talking I think you need to read up on header
files and how they are used. If you are using the struct in more than
one C file then it should be defined in a header file and all C files
that use it then include that header file to get the definition.

Note that object (variables) should not be defined in header files, only
declared with extern.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
goldfita@signalsguru.net
Guest
Posts: n/a
 
      01-04-2006

Flash Gordon wrote:
> (E-Mail Removed) wrote:
> > Flash Gordon wrote:
> >> If you are doing that, then there is a special dispensation for the
> >> *initial* members of a struct when they appear in a union. I.e.
> >>
> >> struct foo {
> >> int type;
> >> char name[NAME_SIZE];
> >> double val;
> >> };
> >>
> >> struct bar {
> >> int type;
> >> char name[NAME_SIZE];
> >> int val;
> >> }
> >>
> >> union foobar {
> >> struct foo foomess;
> >> struct bar barmess;
> >> }
> >>
> >> In the above, you are allowed to use either foo or bar to access the
> >> type and name fields, but from val on you have to use the correct struct
> >> type. So for the type of thing you are discussing the correct method is
> >> to put the common elements at the start of the struct and the elements
> >> that vary at the end. It may simplify getting it right to put all the
> >> initial members in to a struct and doing something like:

> >
> > Yes, it seems to make more sense in this example to put the common
> > members first. I'm confused about this union example though. (I've
> > never used one.) Are you saying the compiler will ensure the top
> > members of foo and bar that are the same will be aligned?

>
> Yes.
>
> > Does that
> > mean the compiler has to be able to see the definitions to make the
> > union?

>
> Of course. That's a bit like asking if a builder needs access to the
> bricks to build a brick wall.
>
> > What if foo and bar were declared elsewhere (with different
> > compiler options or on different compilers)?

>
> If you change compiler options (or compiler) for different translation
> units then potentially all bets are off. After all, some compilers have
> options specifically to change how things will be aligned.
>
> Also, from the way you are talking I think you need to read up on header
> files and how they are used. If you are using the struct in more than
> one C file then it should be defined in a header file and all C files
> that use it then include that header file to get the definition.
>
> Note that object (variables) should not be defined in header files, only
> declared with extern.
> --
> Flash Gordon
> Living in interesting times.
> Although my email address says spam, it is real and I read it.



I'm not sure we're talking about the same thing here. The issue was, I
don't want to define foo and bar because I may not know what's going to
be in them except for type and name. That's why I wasn't sure about
the union version. But I think your struct version can handle that
case.

-Todd

 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      01-04-2006
(E-Mail Removed) wrote:
> Flash Gordon wrote:
>> (E-Mail Removed) wrote:
>>> Flash Gordon wrote:
>>>> If you are doing that, then there is a special dispensation for the
>>>> *initial* members of a struct when they appear in a union. I.e.
>>>>
>>>> struct foo {
>>>> int type;
>>>> char name[NAME_SIZE];
>>>> double val;
>>>> };
>>>>
>>>> struct bar {
>>>> int type;
>>>> char name[NAME_SIZE];
>>>> int val;
>>>> }
>>>>
>>>> union foobar {
>>>> struct foo foomess;
>>>> struct bar barmess;
>>>> }
>>>>
>>>> In the above, you are allowed to use either foo or bar to access the
>>>> type and name fields, but from val on you have to use the correct struct
>>>> type. So for the type of thing you are discussing the correct method is
>>>> to put the common elements at the start of the struct and the elements
>>>> that vary at the end. It may simplify getting it right to put all the
>>>> initial members in to a struct and doing something like:
>>> Yes, it seems to make more sense in this example to put the common
>>> members first. I'm confused about this union example though. (I've
>>> never used one.) Are you saying the compiler will ensure the top
>>> members of foo and bar that are the same will be aligned?


<snip>

> I'm not sure we're talking about the same thing here. The issue was, I
> don't want to define foo and bar because I may not know what's going to
> be in them except for type and name. That's why I wasn't sure about
> the union version. But I think your struct version can handle that
> case.


OK, then in your situation I would agree the struct version I mentioned
else-thread (a struct defining the common initial sequence then used as
the first element of all other structs) is easier. To use the above the
mechanism the user of your code would have to declare things correctly
and declare the union. With a struct defined in your header file for the
common bit, all they need to do is use that struct as the first member
of their struct.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Packed structs vs. unpacked structs: what's the difference? Daniel Rudy C Programming 15 04-10-2006 08:10 AM
Array of structs instead of an array with pointers to structs? Paminu C Programming 5 10-11-2005 07:18 PM
length of an array in a struct in an array of structs in a struct in an array of structs Tuan Bui Perl Misc 14 07-29-2005 02:39 PM
const structs in other structs Chris Hauxwell C Programming 6 04-27-2004 07:03 PM
structs with fields that are structs Patricia Van Hise C Programming 5 04-05-2004 01:37 AM



Advertisments