I have the following piece of code:
struct sched_param {
union {
int sched_priority;
struct rcost_sched_param rcost_params;
};
};
I want to know which of the two parameters is "active". Is there a way for me to do that other than adding a int to the struct sched_param?
struct sched_param {
int type;
union {
int sched_priority;
struct rcost_sched_param rcost_params;
};
}
you can add member named type,save the data which parameters is "active"
No, that's the tricky part here: You'll have to store the information which union entry to use (e.g. using a single char member). Also note that both union entries might not necessarily point to the same locations (as you might expect, e.g. due to packing or endianess), so you can't just read one value and determine whether it's containing a valid value or not, since it's up to the compiler how to implement the struct in the union behind the scenes.
Related
In C, is it possible to define a union within another union? If no, why is it not possible? Or if yes, where can it be used?
Suppose you want to define:
union myun {
int x;
sometype y;
};
where sometype is a typedef defined by a library you're using. If the library happened to implement it as a union type, then this would be a union within a union, and it would make sense because you can't (from a good design standpoint) violate the encapsulation of the library's type.
Yes, it's possible, and useful. The reason is the same reason X within Y is useful for many values of X and Y: compositionality. Programs are built by assembling tiny components into small components into larger components into huge components into... Sometimes a bunch of unions happen to be assembled into a union, and so what?
R..'s answer shows an example where this happens behind the scenes: it just happens that one of the union member types is a union, but you don't know that unless you look at the library implementation.
EDIT However, note that the common idiom for discriminated unions where each member of the union is a structure whose first field is an integral type containing a tag does not extend to nested unions. That is, the following is a common, standard-compliant (N1256 ยง6.5.2.3.5) implementation of discriminated unions in C:
struct generic {
unsigned tag;
};
struct smallnum {
unsigned tag; /*always TAG_SMALLNUM*/
unsigned value;
};
struct bignum {
unsigned tag; /*always TAG_BIGNUM*/
size_t length;
unsigned *p;
};
struct string {
unsigned tag; /*always TAG_STRING*/
size_t length;
char *p;
};
union number {
struct bignum bignum;
struct smallnum smallnum;
};
union object {
struct generic generic;
struct bignum bignum;
struct smallnum smallnum;
struct string string;
};
If you have an union object object x, you can always read its tag as x.generic.tag (or x.bignum.tag or any of the others), no matter what was actually assigned to the object. By using unique tags (discriminators) for the objects.
The following definition is legal, but not useful as you cannot just read the first field of a union level2 object to get the tag: if a union level2 object was written as a union number, you have to read its tag through the number member, and otherwise you have to read its tag through the generic or string member. I wouldn't be surprised if accessing through the wrong member worked on every now existing implementation, but it is not standard-compliant.
union level2 {
struct generic generic;
union number number;
struct string string;
};
Yes it is possible. But I'd tend to stick with the advice of never use unions. The number of situations where unions are the right answer are very small. I suspect there is no situation where a union containing a union is a good idea.
Yes, it is possible. I can't think of a good use of the top of my head, although it would be easy to come up with a contrived example.
Yes, a union may contain another union:
union foo {
int x;
double y;
union bar {
char blah[10];
char *blurga;
} bletch;
};
I can't think of a situation where it would be useful (or even desirable), though.
the below code provided an O/P :
101:name_provided:name_provided
AFAIK a union can hold only one member at a time, but it looks like both values are visible , is that correct or anything wrong with the code.
#include <stdio.h>
struct test1{
char name[15];
};
struct test2{
char name[15];
};
struct data{
int num;
union{
struct test1 test1_struct;
struct test2 test2_struct;
};
};
int main()
{
struct data data_struct={101,"name_provided"};
printf("\n%d:%s:%s",data_struct.num,data_struct.test1_struct.name,data_struct.test2_struct.name);
return 0;
}
A union specifies that both members will be located at the same place in memory. So if you assign to test1_struct and then read from test2_struct, it will interpret the contents of test1_struct as if it were in the format of test2_struct.
In this case, both structures have the same format, so it doesn't make a difference which one you read and write. It generally makes no sense to use a union where both members are equivalent. The usual purpose of a union is to have different types of members, but not need to have separate memory for each of them, because you only need to use one type at a time. See How can a mixed data type (int, float, char, etc) be stored in an array? for a typical use case.
And see Unions and type-punning for the consequences of accessing a different member than the one you assigned to.
I have an anonymous union nested within a struct, as well as other common fields. Is there any reason to place the union in a specific place within the struct (e.g. first or last)?
For example, is this:
typedef struct _Message
{
MessageType type;
union
{
SystemMessageArgs systemArgs;
OtherMessageArgs usbArgs;
};
} Message;
better than this:
typedef struct _Message
{
union
{
SystemMessageArgs systemArgs;
OtherMessageArgs usbArgs;
};
MessageType type;
} Message;
in any way?
The context is embedded-C, specifically TI's MSP430
There may be a possible difference in padding, you can find that out by using sizeof() on both of them and comparing the results. This may be relevant if you are dealing with heavily constrained memory amounts.
Other than that, they are equivalent.
I used a union type in the struct to define whether this person is a student or a staff. When i tried to output the information in the struct array, i found it was hard for me to figure out what kind of this person was ,not to say output the further information. Do not tell me stop using union, sorry, i was asked to do so.
Hers's my simplified data structure:
typedef union student_or_staff{
char *program_name;
char *room_num;
}student_or_staff;
typedef struct people{
char *names;
int age;
student_or_staff s_or_s;
}people[7];
The only way to know what is stored in a union is to include this information in some other place.
There are two common situations that happen when you deal with an array of unions (or structs that hold a union):
All unions in an array hold the same type, or
Each union may hold its own type.
When all unions in an array hold the same type, a single variable that indicates the type the unions hold is sufficient.
When each union could hold a different type, a common approach is to wrap it in a struct, and add a flag indicating which way the union is set. Using your example, the flag should be added to struct people, like this:
enum student_staff_flag {
student_flag
, staff_flag
};
typedef struct people{
char *names;
int age;
enum student_staff_flag s_or_s_flag;
student_or_staff s_or_s;
}people[7];
It is not possible to do this in C but as a workaround you can add a type along your union like this
enum { student_type, staff_type } PEOPLE_TYPE;
typedef union student_or_staff{
char *program_name;
char *room_num;
}student_or_staff;
typedef struct people{
char *names;
int age;
student_or_staff s_or_s;
PEOPLE_TYPE people_type;
}people[7];
Then you just set that along with your union when you assign your struct.
union Data
{
int i;
float f;
char str[20];
} data;
structure Data
{
int i;
float f;
char str[20];
} data;
Here, as I know,"data" is a tag and it is optional. What exactly is it? What advantages can I get by adding a tag while declaring a structure or a union.
Here, as I know,"data" is a tag and it is optional.
No, there is no tag here. A tag indicates which interpretation of a union is correct. For example, if your code assigns data.f and passes data to another function and it reads data.str then you'll have a massive failure in your program that is likely to crash it. The union itself doesn't give the function enough information to know which union member to use.
By adding a tag, you can indicate which interpretation is correct. For example:
struct TaggedData
{
int type;
union Data value;
} taggeddata;
Where type is the tag and indicates what kind of value is stored in the union. A function that reads taggeddata can now use a switch statement and access the correct union member.
Another common name for a tagged data structure is a variant type. Compare to Boost.Variant.