[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Same structures, different names

DSF

4/3/2011 8:11:00 PM

Hello,

I have a situation where I have two structures that are identical
except for the names. A simplified example:

struct foo
{
unsigned long a;
unsigned long b;
};

struct bar
{
unsigned long a;
unsigned long b;
};

I don't have the ability to re-designate either of them, as they
each belong to a different library.

So if I need to pass a function in library "foo" a "bar" variable, I
must create a "foo" variable and copy each member from the "bar"
variable to it. This is not my idea of efficiency.

I figure the answer's one of two things: It's either something I've
missed/forgotten, or it can't be done and I'm SOL.

Thanks!

DSF
28 Answers

jens

4/4/2011 1:38:00 PM

0

On 3 Apr., 22:10, DSF <notava...@address.here> wrote:
> Hello,
>
>   I have a situation where I have two structures that are identical
> except for the names.  A simplified example:
>
>  struct foo
>  {
>    unsigned long a;
>    unsigned long b;
>  };
>
>  struct bar
>  {
>    unsigned long a;
>    unsigned long b;
>  };
>
>   I don't have the ability to re-designate either of them, as they
> each belong to a different library.
>
>   So if I need to pass a function in library "foo" a "bar" variable,


int func_w_foo_arg( struct foo *f ) { (...) };


int caller(void)
{
struct bar b;

(...)

func_w_foo_arg( (struct foo *) &b );


}








Tom St Denis

4/4/2011 2:35:00 PM

0

On Apr 3, 4:10 pm, DSF <notava...@address.here> wrote:
> Hello,
>
>   I have a situation where I have two structures that are identical
> except for the names.  A simplified example:
>
>  struct foo
>  {
>    unsigned long a;
>    unsigned long b;
>  };
>
>  struct bar
>  {
>    unsigned long a;
>    unsigned long b;
>  };
>
>   I don't have the ability to re-designate either of them, as they
> each belong to a different library.
>
>   So if I need to pass a function in library "foo" a "bar" variable, I
> must create a "foo" variable and copy each member from the "bar"
> variable to it.  This is not my idea of efficiency.
>
>   I figure the answer's one of two things: It's either something I've
> missed/forgotten, or it can't be done and I'm SOL.

Why would you create two identical but differently named structs? To
me, *THAT* is your inefficiency.

Tom

David Resnick

4/4/2011 2:38:00 PM

0

On Apr 4, 10:34 am, Tom St Denis <t...@iahu.ca> wrote:
> On Apr 3, 4:10 pm, DSF <notava...@address.here> wrote:
>
>
>
> > Hello,
>
> >   I have a situation where I have two structures that are identical
> > except for the names.  A simplified example:
>
> >  struct foo
> >  {
> >    unsigned long a;
> >    unsigned long b;
> >  };
>
> >  struct bar
> >  {
> >    unsigned long a;
> >    unsigned long b;
> >  };
>
> >   I don't have the ability to re-designate either of them, as they
> > each belong to a different library.
>
> >   So if I need to pass a function in library "foo" a "bar" variable, I
> > must create a "foo" variable and copy each member from the "bar"
> > variable to it.  This is not my idea of efficiency.
>
> >   I figure the answer's one of two things: It's either something I've
> > missed/forgotten, or it can't be done and I'm SOL.
>
> Why would you create two identical but differently named structs?  To
> me, *THAT* is your inefficiency.
>
> Tom

As OP said, they are in libraries that are out of his control.
Sometimes you just have to deal with what is. Haven't you ever had to
deal with an interface you didn't like but was frozen?

-David

Keith Thompson

4/4/2011 3:13:00 PM

0

DSF <notavalid@address.here> writes:
> I have a situation where I have two structures that are identical
> except for the names. A simplified example:
>
> struct foo
> {
> unsigned long a;
> unsigned long b;
> };
>
> struct bar
> {
> unsigned long a;
> unsigned long b;
> };
>
> I don't have the ability to re-designate either of them, as they
> each belong to a different library.
>
> So if I need to pass a function in library "foo" a "bar" variable, I
> must create a "foo" variable and copy each member from the "bar"
> variable to it. This is not my idea of efficiency.
>
> I figure the answer's one of two things: It's either something I've
> missed/forgotten, or it can't be done and I'm SOL.

It might be helpful to have some more information about the actual
structures. (I presume they aren't really called "foo" and "bar".)

You've shown us two struct types with exactly the same members
(same member names and types). Do these two libraries really
declare identical types? Are they certain to remain identical in
future versions of both libraries? Is the layout of both structures
imposed by some external interface?

Why does it make sense to pass a "bar" variable to a function in the
"foo" library?

"Data, data, data! I cannot make bricks without clay!"

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Morris Keesan

4/4/2011 7:21:00 PM

0

On Mon, 04 Apr 2011 09:37:33 -0400, jens <au1064@googlemail.com> wrote:

> On 3 Apr., 22:10, DSF <notava...@address.here> wrote:
>> Hello,
>>
>>   I have a situation where I have two structures that are identical
>> except for the names.  A simplified example:
>>
>>  struct foo
>>  {
>>    unsigned long a;
>>    unsigned long b;
>>  };
>>
>>  struct bar
>>  {
>>    unsigned long a;
>>    unsigned long b;
>>  };
>>
>>   I don't have the ability to re-designate either of them, as they
>> each belong to a different library.
>>
>>   So if I need to pass a function in library "foo" a "bar" variable,
>
>
> int func_w_foo_arg( struct foo *f ) { (...) };
>
>
> int caller(void)
> {
> struct bar b;
>
> (...)
>
> func_w_foo_arg( (struct foo *) &b );
>
>
> }

Or, if you really need to pass the actual struct and not a pointer to it,
func_w_foo_arg(*(struct foo *)&b);


--
Morris Keesan -- mkeesan@post.harvard.edu

DSF

4/5/2011 6:24:00 AM

0

On Mon, 04 Apr 2011 08:13:09 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>DSF <notavalid@address.here> writes:
>> I have a situation where I have two structures that are identical
>> except for the names. A simplified example:
>>
>> struct foo
>> {
>> unsigned long a;
>> unsigned long b;
>> };
>>
>> struct bar
>> {
>> unsigned long a;
>> unsigned long b;
>> };
>>
>> I don't have the ability to re-designate either of them, as they
>> each belong to a different library.
>>
>> So if I need to pass a function in library "foo" a "bar" variable, I
>> must create a "foo" variable and copy each member from the "bar"
>> variable to it. This is not my idea of efficiency.
>>
>> I figure the answer's one of two things: It's either something I've
>> missed/forgotten, or it can't be done and I'm SOL.
>
>It might be helpful to have some more information about the actual
>structures. (I presume they aren't really called "foo" and "bar".)
>
>You've shown us two struct types with exactly the same members
>(same member names and types). Do these two libraries really
>declare identical types? Are they certain to remain identical in
>future versions of both libraries? Is the layout of both structures
>imposed by some external interface?
See below.
>
>Why does it make sense to pass a "bar" variable to a function in the
>"foo" library?
Ditto.

>
>"Data, data, data! I cannot make bricks without clay!"

What I posted above is not the exact situation, it's a watered-down
example.

Here is the full story.

The reason I did not post the actual structure data is that there
are a host (as in large number) of sacred cows in this group one must
not go around tipping, and there is a host (as in army) of people
ready to textually rip you a new one if you tip a cow or two. :o)

The supine bovine here is that the answer I was looking for need not
be portable, so I decided to use a generic example. In reality, the
first "library" is actually part of Windows and the second is my own.

The Windows "struct" is defined as:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;

DWORD = unsigned long.
LONG = long.
LONGLONG (see below).

Oops. It's a union. The above is from the WINNT.H file. My Windows
API help file defines it as a structure. With a little more checking,
MS's site has this comment:

"The LARGE_INTEGER structure is actually a union. If your compiler has
built-in support for 64-bit integers, use the QuadPart member to store
the 64-bit integer. Otherwise, use the LowPart and HighPart members to
store the 64-bit integer."

To make matters even stranger, the LONGLONG above that defines
QuadPart is a typedef of double on my system. Although it's the same
number of bits as two longs, I don't believe anything other than zero
in both LowPart and HighPart will be represented correctly in
QuadPart. So I just ignore it and use the LowPart and HighPart.


My structure is defined as:
typedef struct tag_int64 {
unsigned long ldw;
unsigned long hdw;
} int64;

You might be asking why I just didn't use MS's LARGE_INTEGER for my
library. The main reason would be that I'd written the library at a
time where I wasn't using any MS API calls that used LARGE_INTEGER.
Another reason was that it just didn't match my style of programming.
I prefer my variable names to be all lower case, and in the case of
structure members, short. Having to deal with something like:

void foo(unsigned long startl, unsigned long starth);
LARGE_INTEGER count;

Then later,
foo(count.u.LowPart, count.u.HighPart);

isn't a good fit for me.

When I realized that I was going to be dealing with a lot of MS API
calls that use LARGE_INTEGER, I started looking for a better solution
than copying the individual members.

Sorry to be so long winded, but that's the whole story.

Ben Bacarisse's suggestion of a union works perfectly. I use:

typedef union tag_li64 {
int64 i64;
LARGE_INTEGER li;
} li64;

li64 count;

and use count.li for the MS API
and count.i64 for mine.

DSF

P.S. Yes, I know that the high 32 bits of LARGE_INTEGER are signed
whilst they are unsigned for int64. It's not a concern for what I'm
doing.

DSF

4/5/2011 6:26:00 AM

0

On Mon, 4 Apr 2011 07:38:10 -0700 (PDT), David Resnick
<lndresnick@gmail.com> wrote:

>On Apr 4, 10:34 am, Tom St Denis <t...@iahu.ca> wrote:
>> On Apr 3, 4:10 pm, DSF <notava...@address.here> wrote:
>> >   So if I need to pass a function in library "foo" a "bar" variable, I
>> > must create a "foo" variable and copy each member from the "bar"
>> > variable to it.  This is not my idea of efficiency.
>>
>> >   I figure the answer's one of two things: It's either something I've
>> > missed/forgotten, or it can't be done and I'm SOL.
>>
>> Why would you create two identical but differently named structs?  To
>> me, *THAT* is your inefficiency.
>>
>> Tom
>
>As OP said, they are in libraries that are out of his control.
>Sometimes you just have to deal with what is. Haven't you ever had to
>deal with an interface you didn't like but was frozen?
>
>-David
What he said :o) ...well, almost. See my reply to Keith Thompson.

DSF

Keith Thompson

4/5/2011 6:48:00 AM

0

DSF <notavalid@address.here> writes:
[...]
> The reason I did not post the actual structure data is that there
> are a host (as in large number) of sacred cows in this group one must
> not go around tipping, and there is a host (as in army) of people
> ready to textually rip you a new one if you tip a cow or two. :o)
>
> The supine bovine here is that the answer I was looking for need not
> be portable, so I decided to use a generic example. In reality, the
> first "library" is actually part of Windows and the second is my own.

Hmm. That's not something I'd be particularly concerned about if
I were in your position. My own attitude is that C code should
be a portable as possible, but no more so. One of C's greatest
strengths is actually the ability to use it to write *non-portable*
code. I think most people here would be glad to offer non-portable
solutions where necessary -- as long as you don't mind an occasional
reminder that they're non-portable.

> The Windows "struct" is defined as:
> typedef union _LARGE_INTEGER {
> struct {
> DWORD LowPart;
> LONG HighPart;
> } u;
> LONGLONG QuadPart;
> } LARGE_INTEGER;
>
> DWORD = unsigned long.
> LONG = long.
> LONGLONG (see below).
>
> Oops. It's a union. The above is from the WINNT.H file. My Windows
> API help file defines it as a structure. With a little more checking,
> MS's site has this comment:
>
> "The LARGE_INTEGER structure is actually a union. If your compiler has
> built-in support for 64-bit integers, use the QuadPart member to store
> the 64-bit integer. Otherwise, use the LowPart and HighPart members to
> store the 64-bit integer."
>
> To make matters even stranger, the LONGLONG above that defines
> QuadPart is a typedef of double on my system. Although it's the same
> number of bits as two longs, I don't believe anything other than zero
> in both LowPart and HighPart will be represented correctly in
> QuadPart. So I just ignore it and use the LowPart and HighPart.

So all this stuff is defined by Windows itself? Ok.

> My structure is defined as:
> typedef struct tag_int64 {
> unsigned long ldw;
> unsigned long hdw;
> } int64;
>
> You might be asking why I just didn't use MS's LARGE_INTEGER for my
> library. The main reason would be that I'd written the library at a
> time where I wasn't using any MS API calls that used LARGE_INTEGER.
> Another reason was that it just didn't match my style of programming.
> I prefer my variable names to be all lower case, and in the case of
> structure members, short. Having to deal with something like:
>
> void foo(unsigned long startl, unsigned long starth);
> LARGE_INTEGER count;
>
> Then later,
> foo(count.u.LowPart, count.u.HighPart);
>
> isn't a good fit for me.

And now, I'm sorry to say, you're paying the price. I have my
own very strong feelings about coding style, and the declaration
of LARGE_INTEGER violates several of them -- but if I'm going to
be using interfaces that are defined in terms of it, I'll grit my
teeth and use it.

> When I realized that I was going to be dealing with a lot of MS API
> calls that use LARGE_INTEGER, I started looking for a better solution
> than copying the individual members.

How difficult would to be to change your own code to use
LARGE_INTEGER the way the system defines it? I'm not saying
that's necesarily the best approach, but you might think about it.
(Unless there's other existing code, outside your control, that
depends on "int64" the way your library defines it.)

Of course, since you've already got a working solution, you can
reasonably ignore my advice.

> Sorry to be so long winded, but that's the whole story.
>
> Ben Bacarisse's suggestion of a union works perfectly. I use:
>
> typedef union tag_li64 {
> int64 i64;
> LARGE_INTEGER li;
> } li64;
>
> li64 count;
>
> and use count.li for the MS API
> and count.i64 for mine.

Yes, that's a reasonable solution.

> DSF
>
> P.S. Yes, I know that the high 32 bits of LARGE_INTEGER are signed
> whilst they are unsigned for int64. It's not a concern for what I'm
> doing.

Right. It depends on several assumptions about integer
representations -- but since it's Windows-specific anyway, that's
not a big problem.

(Unless you want to port Windows to a machine that doesn't satisfy
those assumptions. Windows has actually been ported to systems
other than x86, but I believe they're all little-endian. Of course
that's *way* outside the scope of what you're working on.)

Some might argue that since this is Windows-specific, it's off-topic
and better discussed in, say, comp.os.ms-windows.programmer.win32.
But since you've provided the C declarations of the relevant
Windows-specific types, I'd say it's more about C than about Windows;
similar issues could arise on any OS.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Jorgen Grahn

4/6/2011 2:20:00 PM

0

On Sun, 2011-04-03, DSF wrote:
> Hello,
>
> I have a situation where I have two structures that are identical
> except for the names. A simplified example:
>
> struct foo
> {
> unsigned long a;
> unsigned long b;
> };
>
> struct bar
> {
> unsigned long a;
> unsigned long b;
> };
>
> I don't have the ability to re-designate either of them, as they
> each belong to a different library.
>
> So if I need to pass a function in library "foo" a "bar" variable, I
> must create a "foo" variable and copy each member from the "bar"
> variable to it. This is not my idea of efficiency.

Create a

static inline struct bar foo2bar(struct foo val);

and let the optimizer deal with it. With a bit of luck the foo2bar()
call just melts away into nothing -- as it should.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

DSF

4/8/2011 2:58:00 AM

0

On 6 Apr 2011 14:19:41 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se>
wrote:

>
>Create a
>
>static inline struct bar foo2bar(struct foo val);
>
>and let the optimizer deal with it. With a bit of luck the foo2bar()
>call just melts away into nothing -- as it should.
>
>/Jorgen

I have it working, but in the pursuit of knowledge I want to know if
I understand what you're saying. The actual function would be:

static inline struct bar foo2bar(struct foo val)
{
struct bar r;
r.a = val.a;
r.b = val.b;
return r;
}

I then use foo2bar wherever I have a "foo" and a "bar" is needed?

If this is the case, this would cut down on typing, but still
produces more code than I'd like. There wouldn't be a function call,
but the "copy val to r" code would still be created for each "call".

Second problem:

The above prototype and function compile fine as C++, but produce
syntax errors unless "inline" is removed.

DSF