How to check if a union in C has not been "initialized"? - c

Can I check if union is null in c? For example:
union{ char * name, struct Something * something ... }someUnion;
Is there a way to check if no element has been initialized, without doing element vise check?
Thanks.

No, not without adding a specific flag for that purpose. For example:
struct someStruct {
int initialized;
union {
char *name;
struct Something *something;
};
};
You could even store a flag instead of initialized that indicates which kind of data the union contains. This is commonly called a Tagged union.

Yes, under the conditions that all members of the union are of pointer type or a integral type and with initialization you mean a value which is not NULL has been assigned, it is sufficient to check one element for NULL.
union {
char * name;
struct Something * something; } someUnion;
if (someUnion.name != 0) {
// here you know that someUnion.something is not NULL too.
// You don't know if it has been initialized as char*
// or as struct something* though. Presumeably since
// it is a unionboth interpretations make some sense.
}

Related

What does 'Tag' of union and structure do?

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.

Assigning the value of an union containing structures to NULL in c programming

I have a union and 2 structures in the following format and I need to set one of them to NULL.
For example m = NULL or t = NULL;
typedef struct
{
char *population;
char *area;
} metropolitan;
typedef struct
{
char *airport;
char *type;
} tourist;
typedef union
{
tourist t;
metropolitan m;
} ex;
First of all, the members of your union are not pointers, so it doesn't make all that much sense setting the value to NULL.
Second, the way a union works is that if you set one of the members, you set the others as well. More precisely, all members of a union have the address, but different types. I.e. the different types gives you a way to interpret the same area in memory as multiple types at once.
To differentiate from a strutct:
struct a {
unsigned b;
char *c;
};
In this case, the appropriate number of bytes are allocated for each of the fields a and s, one after the other.
union a {
unsigned b;
char *c;
};
Here, the values of b and c are stored in the same address. I.e. if you're setting a.b to 0, a readout from a.c would give NULL (numeric 0x0).
Since tourist and metropolitan are structs, you cannot assign NULL to them.
But, if you declare like
typedef union
{
tourist* t;
metropolitan* m;
} ex;
you can do
ex e;
e.t=NULL; //which makes e.m=NULL as well
With unions you need to tell them apart.
So define a structure thus:
typedef enum { MET, TOURIST} Chap;
typedef struct {
Chap human;
union {
tourist t;
metropolitan m;
}
} Plonker;
Then you know what is what an then set the appropriate values
i.e
Plonker p;
p.human = MET;
p.m.population = NULL;
... etc

Working with a union of structs in C

Say I have the following types:
typedef struct TYPEA
{
int type;
char[12] id;
} TYPEA;
typedef struct TYPEB
{
int type;
int value;
} TYPEB;
I want to use create a union of these types and 'int', so that I can access the "type" int without needing to know whether TYPEA or TYPEB is stored in the union (the value of int lets me determine which is actually stored there). I can't get the right syntax though.
My union:
typedef union MEMBER
{
int type;
struct TYPEA a;
struct TYPEB b;
} MEMBER;
The union is accessed via:
typedef struct WRAPPER
{
union MEMBER* member;
struct WRAPPER* next;
} WRAPPER;
Questions:
(With 'w' as a pointer to an allocated WRAPPER struct) Accessing using w->member->a.id gives "request for member 'id' in something not a structure or union.
Can I assign a pointer to an already malloc'd TYPEA/B to w->member directly? Or does a union need to be malloced specially?
Thanks.
Use w->member->type.
You need to allocate the union specifically.
One note that may be a point of misunderstanding is that the union holds EITHER the int, or TYPEA, or TYPEB, so in particular you cannot rely on your int type; in the union to tell you which struct the union holds.
Edit to respond to question in comments:
You probably want something like this:
struct TYPEA {
char data[30]; // or whatever
};
struct TYPEB {
double x, y; // or whatever
};
struct some_info {
int type; // set accordingly
union {
struct TYPEA a;
struct TYPEB b;
} data; // access with some_info_object.data.a or some_info_object.data.b
};
You defined the member field as a pointer, so you should use
w->member->type instead of w->member.type.
You should malloc the union type. When you allocate a union, you'll get a structure that has a sizeof equal to the largest element in the union. If you try to copy structures into union pointers, you'll mess up the alignment.
w->member.type should be w->member->type because w->member is a pointer.
I don't know off the top of my head whether C will let you assign a TYPEA* or TYPEB* to a MEMBER* - somehow I doubt it. You can always (MEMBER*) it, but I would consider recomposing the structs to remove the int tag and instead declare one struct that includes the tag and a union of TYPEA and TYPEB. The structs ideally shouldn't need to be concerned with the fact that they're in a union.
You might want to check out the code in my question:
Union of structs with common first member
Essentially, I do what you want but I'm using an inner struct (contained in the example) that's common to the two types. This struct can then be cast to gain access to the common elements of both types.

access union member in c

I have a question about union in c language
for example:
typedef struct {
int a;
float c;
}Type1;
typedef struct {
int b;
char d;
}Type2;
union Select {
Type1 type1;
Type2 type2;
};
void main() {
Select* select;
//can we access type1 first and then access type2 immediately? like this way:
select->type1.a;
select->type2.b;
//after access type1, and then access type2 immediately, can we get the value b of type2?
//I modify the first post a little bit, because it is meanless at the beginning.
}
This is guaranteed to work by ISO/IEC 9899:1999 (see the draft here), 6.5.2.3 5:
One special guarantee is made in order to simplify the use of unions: if a union contains
several structures that share a common initial sequence (see below), and if the union
object currently contains one of these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of the complete type of the union is
visible. Two structures share a common initial sequence if corresponding members have
compatible types (and, for bit-fields, the same widths) for a sequence of one or more
initial members.
Yes, that is correct. In your example (ignoring the uninitialised pointer) the value of type1.a and type2.b will always be the same for any given instance of Select.
In your example it will work since both are types int
Normally you need a discriminator to know which union is used at a time.
The union has the size of the largest data type (if I recall corectly) and you set/check the type each time to know which data type to access:
struct myStruct {
int type;
union Select {
Type1 type1;
Type2 type2;
};
};
You would do a check before accessing to know how to use the union:
myStruct* aStruct;
//init pointer
if(aStruct->type == TYPE1)//TYPE1 is defined to indicate the coresponding type
{
//access fields of type1
aStruct->type1.a = //use it
}
Also before you should have done: aStruct->type = TYPE1
Yeah, you can access both of them when ever you want. basically select->type1 and select->type2 are pointers to the same location in memory. It's the progeammer job to know what sits in that location in memory, Usually by a flag:
union Select {
Type1 type1;
Type2 type2;
};
struct SelectType {
bool isType1;
Select select;
};
int getValue (struct SelectType s){
if (s.IsType1){
return s.type1.a;
} else {
return s.type2.b;
}
}
void main() {
struct SelectType select;
int value;
select.type1.a = 5;
select.isType1 = true;
select.type2.4 = 5;
select.isType1 = false;
value = getValue (select);
}
Yes we can. it's value does not change in this case. It's not wrong, but it is meaningless.
by the way, You forget to allocate memory for the pointer 'select'?
I really want to help, but my english is not very good. And this is my first post. So if I have said something wrong, tell me.
Yes, you can, because main has the scope for your union declaration.
Quote from the final version of the C99 standard.
The following is not a valid fragment (because the union type is not visible within function f)
struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 *p1, struct t2 *p2)
{
if (p1->m < 0)
p2->m = -p2->m;
return p1->m;
}
int g()
{
union {
struct t1 s1;
struct t2 s2;
} u;
/* ... */
return f(&u.s1, &u.s2);
}
all members in union reside in the same memory location.
its usually to access the same block of memory it more than one way.
for example , you can define:
union
{
char a[100];
int b[50];
}x;
union size will be 100 bytes , and read from b[0] is like reading a[0] and a[1] together

Why can union be used this way?

Isn't it true that members in union are exclusive, you can't refer to the other if you already refer to one of them?
union Ptrlist
{
Ptrlist *next;
State *s;
};
void
patch(Ptrlist *l, State *s)
{
Ptrlist *next;
for(; l; l=next){
next = l->next;
l->s = s;
}
}
But the above is referring to both next and s at the same time, anyone can explain this?
A union only defines that
&l->next == &l->s
that's all. There is no language-restriction of first accesses.
As others have already pointed out, all members of a union are active at all times. The only thing to consider is whether the members are each in a valid state.
If you ever do want some level of exclusivity, you would instead require a tagged union. The basic idea is to wrap the union in a struct, and the struct has a member identifying which element in the union should be used. Take this example:
enum Tag {
FIRST,
SECOND
};
struct {
Tag tag;
union {
int First;
double Second;
};
} taggedUnion;
Now taggedUnion could be used like:
if(taggedUnion.tag == FIRST)
// use taggedUnion.First;
else
// use taggedUnion.Second
Yes it's supposed to be like that. Both *s and *next point to the same memory location. And you can use both at the same time.. they are not exclusive.
You are performing an assignment to next from l->next. Then, you "overwrite" l->s through the assignment l->s = s.
When you assign to l->s, it overwrites the memory held in l->next. If next and s are the same "size", then both likely could be "active" at the same time.
No, it's not true. You can use any member of a union at any time, although the results if you read a member that wasn't the one most recently written to are a little bit complicated. But that isn't even happening in your code sample and there's absolutely nothing wrong with it. For each item in the list its next member is read and then its s member is written, overwriting its next.
See http://publications.gbdirect.co.uk/c_book/chapter6/unions.html for an introductory discussion on unions.
Basically, it's an easy way to do type casting in advance. So, instead of having
int query_my_data(void *data, int data_len) {
switch(data_len) {
case sizeof(my_data_t): return ((my_data_t *)data)->value;
case sizeof(my_other_data_t): return ((my_other_data_t *)data)->other_val;
default: return -1;
}
You could simplify it by doing
typedef struct {
int data_type;
union {
my_data_t my_data;
my_other_data_t other_data;
} union_data;
} my_union_data_t;
int query_my_data(my_union_data_t *data) {
switch(data->data_type) {
case TYPE_MY_DATA: return data->union_data.my_data.value;
case TYPE_MY_OTHER_DATA: return data->union_data.other_data.other_val;
default: return -1;
}
Where my_data and other_data would have the same starting address in memory.
An union is similar to a struct, but it only allocates memory for a variable. The size of the union will be equal to the size of the largest type stored in it. For example:
union A {
unsigned char c;
unsigned short s;
};
int sizeofA = sizeof(A); // = 2 bytes
union B {
unsigned char c[4];
unsigned short s[2];
unsigned int i;
};
int sizeofB = sizeof(B); // = 4 bytes
In the second example, s[0] == (c[1] << 8) & #ff00 | c[0];. The variables c, s and i overlap.
B b;
// This assignment
b.s[0] = 0;
// is similar to:
b.c[0] = 0;
b.c[1] = 0;
An union is restricted to primitive types and pointers. In C++, you cannot store classes in a union. All other rules remain basically the same as for a structure, such as public access, stack allocation and such.
Thus, in your example you must use a struct instead of an union.

Resources