Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Struct casting

Reply
Thread Tools

Struct casting

 
 
Ben Pfaff
Guest
Posts: n/a
 
      12-05-2011
Edward Rutherford <(E-Mail Removed)> writes:

> Who is right here by the letter of the law?


Others already gave the answer. Here's the quote from the
standard:

A pointer to a structure object, suitably converted, points
to its initial member (or if that member is a bit-field,
then to the unit in which it resides), and vice versa.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}
 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      12-06-2011
Le 05/12/11 22:52, Edward Rutherford a écrit :
> This was pulled up at a code review. Code was similar to this:
>
> struct foo {
> int bar;
> int baz;
> } f;
>
> int * i = (int *) f;
>
> The only way this could go wrong is if the struct contains padding before
> its first member, but I don't think this would ever happen in practice
> --- maybe on theoretical perverse implementations like the ones you guys
> like to play with
>
> Who is right here by the letter of the law?
>
> Cheers
> Edward


This is a mistake. Instead of writing

int *i = &f.bar; // 16 characters

you write

int * i = (int *) f; // 20 characters

AND (most important):

Now, the "bar" member MUST be the first member of the
structure! And, as Murphy's Law states, sombody will
add a member to the struct foo in the new version,
2 years from here.

WHO will remember that in another file there was an
implicit dependency as to "bar" being the first member?

This code is unmaintainable, it provokes a bug if
ANY modification is done to "bar" within the structure.

Suppose that "bar" member is eliminated. Instead of
provokinbg a compiler error and forcing you to change
the dependent code, the code will silently compile
and provoke a VERY hard debugging session.

I see no justification whatsoever for writing code
like that.

jacob

P.S. Anyway your code doesn't compile, as others have said.


 
Reply With Quote
 
 
 
 
Malcolm McLean
Guest
Posts: n/a
 
      12-06-2011
On Dec 6, 9:29*am, jacob navia <(E-Mail Removed)> wrote:
>
> int * i = (int *) f; // 20 characters
>
> I see no justification whatsoever for writing code
> like that.
>

As the snippet goes, no.

But "bar" might in fact be type a identifier field

foodoo(struct foo *f)
{
switch( *( int *) f)
{
case REALLYABAR:
dobar(f); return;
case REALLYAFOO:
dofoo(f); return;
}
}

This is arguably better than switch(foo->bar) because it makes clear
that code will onyl work if the identifier is the first member.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-06-2011
On 12/ 6/11 09:15 PM, Malcolm McLean wrote:
> On Dec 6, 9:29 am, jacob navia<(E-Mail Removed)> wrote:
>>
>> int * i = (int *) f; // 20 characters
>>
>> I see no justification whatsoever for writing code
>> like that.
>>

> As the snippet goes, no.
>
> But "bar" might in fact be type a identifier field
>
> foodoo(struct foo *f)
> {
> switch( *( int *) f)
> {
> case REALLYABAR:
> dobar(f); return;
> case REALLYAFOO:
> dofoo(f); return;
> }
> }
>
> This is arguably better than switch(foo->bar) because it makes clear
> that code will onyl work if the identifier is the first member.


Better still is to give the first member a name that identifies is as
the type identifier field. The X XEvent union is a good example of this.

--
Ian Collins
 
Reply With Quote
 
Lauri Alanko
Guest
Posts: n/a
 
      12-06-2011
In article <(E-Mail Removed)>,
Keith Thompson <(E-Mail Removed)> wrote:
> There cannot be any padding before the first member. The code is safe,
> but poor style. Presumably the member "bar" was given a name for a
> reason; just use that name:
>
> int *i = &f.bar;
>
> Unless, for some odd reason, you specifically want the address of
> the first member of the struct, and you're sure it's an int without
> being sure of its name.


It's a common idiom to simulate poor man's subtyping for structs by
placing the supertype struct as the first member of the subtype
struct, and then casting between struct pointer types. It may even be
that the members of the structs are hidden from client code (or at
least considered private), so the public interface might only say that
a subtype struct pointer can be cast to the supertype pointer (and
back again) without saying anything about the names of the members.

Then again, the direct address-of-member approach, along with a
containerof macro, gives you multiple inheritance, which might be
useful.


Lauri
 
Reply With Quote
 
Joe keane
Guest
Posts: n/a
 
      12-08-2011
In article <jbjeed$c1v$(E-Mail Removed)>,
Edward Rutherford <(E-Mail Removed)> wrote:
>Who is right here by the letter of the law?


Letter of law, 'good idea' is often different.

It's right, but when someone comes along and mofidies your code,
is it likely to do what they expect?

Of course you put a comment that that member needs to be first, right?
 
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
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Up casting and down casting Sosuke C++ 2 12-20-2009 03:24 PM
Problem with depracated casting method (down casting) Wally Barnes C++ 3 11-20-2008 05:33 AM
Another question about inheritance (up-casting and down-casting) kevin Java 11 01-08-2005 07:11 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments