473,473 Members | 2,074 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Returning common field of multiple structs

Hello all,
I wonder if there's a way to obtain a given field from different structs.
Something like this:

struct sDigital {
char Label[255];
int Something;
} tDigital;

struct sAnalog {
double SomethingElse;
char Label[255];
} tAnalog;

char *GetLabel(void* DigOrAnal) {
return DigOrAnal->Label;
}

I know that doesn't work and I have to add a type variable indicator and a
slew of 'if' tests. But I wonder if there are some simplifying tricks.
--
Guillaume Dargaud
http://www.gdargaud.net/
Nov 21 '08 #1
4 1676
Guillaume Dargaud wrote:
Hello all,
I wonder if there's a way to obtain a given field from different structs.
Something like this:

struct sDigital {
char Label[255];
int Something;
} tDigital;

struct sAnalog {
double SomethingElse;
char Label[255];
} tAnalog;

char *GetLabel(void* DigOrAnal) {
return DigOrAnal->Label;
}

I know that doesn't work and I have to add a type variable indicator and a
slew of 'if' tests. But I wonder if there are some simplifying tricks.
Not that I can think of. If you're free to rearrange the
structs so you can put Label first, it's easily solved -- but
as shown, I think you're out of luck. No "MOVE CORRESPONDING"
in C, I'm afraid.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 21 '08 #2
Guillaume Dargaud wrote:
Hello all,
I wonder if there's a way to obtain a given field from different structs.
Something like this:

struct sDigital {
char Label[255];
int Something;
} tDigital;

struct sAnalog {
double SomethingElse;
char Label[255];
} tAnalog;

char *GetLabel(void* DigOrAnal) {
return DigOrAnal->Label;
}

I know that doesn't work and I have to add a type variable indicator and a
slew of 'if' tests. But I wonder if there are some simplifying tricks.
Yes; the simplifying trick is not to fall into this trap. If you find that
it's happening, /stop/ and think about what it implies about your design.

The most obvious fix is to use a struct with a Label field (which might
usefully be `char*`, not `char[]`, depending) and a union of sDigital
and sAnalog. For that you might want your type indicator and if-stew.
But at least you've got rid of one tripwire.

(I say "stew" not "slew" in homage to the signature.)

--
"It is seldom good news." ~Crystal Ball~, /The Tough Guide to Fantasyland/

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Nov 21 '08 #3
On Nov 21, 6:13*am, "Guillaume Dargaud"
<use_the_form_on_my_contact_p...@www.gdargaud.netw rote:
Hello all,
I wonder if there's a way to obtain a given field from different structs.
Something like this:

struct sDigital {
*char Label[255];
*int Something;

} tDigital;

struct sAnalog {
*double SomethingElse;
*char Label[255];

} tAnalog;

char *GetLabel(void* DigOrAnal) {
* * return DigOrAnal->Label;

}

I know that doesn't work and I have to add a type variable indicator and a
slew of 'if' tests. But I wonder if there are some simplifying tricks.
--
Guillaume Dargaudhttp://www.gdargaud.net/
Chris Dollin's suggestion is the right one; redesign your types so
that you have a single struct type with variant members for analog and
digital:

typedef struct sComm
{
char Label[255];
union {
tdigital digitalStuff;
tanalog analogStuff;
} digitalOrAnalog;
} tComm;

Having said that, here's one trick I've used in the past, and I think
it's applicable generally (but don't take my word for it). The
address of the first member of a struct object is the same as the
address of the struct object itself. You could rearrange your struct
definitions so that Label is the first member of both:

typedef struct sDigital
{
char Label[255];
...
} tDigital;

typedef struct sAnalog
{
char Label[255];
...
} tAnalog;

That way, a pointer to the struct can easily be cast into a pointer to
the Label buffer:

tDigital d;
char *dlabel = (char *) &d; // dlabel now points to d.Label
tAnalog a;
char *alabel = (char *) &a; // alabel now points to a.Label

Obviously, that's a bit ugly and non-intuitive, which is why you
should go with Chris' suggestion.
Nov 21 '08 #4
Guillaume Dargaud wrote:
I wonder if there's a way to obtain a given field from different structs.
Something like this:

struct sDigital {
char Label[255];
int Something;
} tDigital;

struct sAnalog {
double SomethingElse;
char Label[255];
} tAnalog;

char *GetLabel(void* DigOrAnal) {
return DigOrAnal->Label;
}

I know that doesn't work and I have to add a type variable indicator and a
slew of 'if' tests. But I wonder if there are some simplifying tricks.
Give the above type definitions, there are no "simplifying tricks"
besides a simple macro

#define GetLabel(DigOrAnal) ((DigOrAnal)->Label)

If you can change the types, the alternative approach would be to
simulate a C++-like class hierarchy

struct sLabeled {
char Label[255];
};

struct sDigital {
sLabeled Label;
int Something;
} tDigital;

STATIC_ASSERT(offsetof(sDigital, Label) == 0);

struct sAnalog {
sLabeled Label;
double SomethingElse;
} tAnalog;

STATIC_ASSERT(offsetof(sAnalog, Label) == 0);

char *GetLabel(void* DigOrAnal) {
/* assert(<make sure it is really safe>); */
return ((sLabeled*) DigOrAnal)->Label;
}

...
sDigital d;
sAnalog a;
...
char *dl = GetLabel(&d);
char *al = GetLabel(&a);

Of course, it is a good idea to put a bunch of safeguard into this
dangerous code, which will perform a run-time check of the data passed
to 'GetLabel' at least in "debug" configuration of the program (like add
a signature to 'sLabeled').

--
Best regards,
Andrey Tarasevich
Nov 21 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Samuel Hon | last post by:
Hi I'm not sure what the best approach for this is: I have a stored procedure which I would like to use to return several output values instead of returning a recordset. CREATE PROCEDURE...
11
by: Bradford Chamberlain | last post by:
I work a lot with multidimensional arrays of dynamic size in C, implementing them using a single-dimensional C array and the appropriate multipliers and offsets to index into it appropriately. I...
4
by: Adrian20XX | last post by:
Hi, Hi, I have a typedefed struct, and later when I declare multiple const structures and want to use a field of one in an inialization, I get the following error: "error C2099: initializer is not...
160
by: DiAvOl | last post by:
Hello everyone, Please take a look at the following code: #include <stdio.h> typedef struct person { char name; int age; } Person;
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.