Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer to union member

I have a struct:

struct TypeValue{
 u8 type;
 union{
   u8 u8value;
   s8 s8value;
 }value;
}

Depending on type var we can have value from u8value or s8value. Now I have a struct TypeValue and I want to get the void pointer to the value element (dont care pointer type), which one is correct:

void *ptr = &typevalue.value (1)
OR
void *ptr = &typevalue.value.u8value (2)

(put this in a for loop to find correct value depending on type)

Of course (2) is a correct way but I have to loop through the data type to get the correct pointer to correct value. But question is if (1) is correct as I am wondering if the pointer to the union is equal to the pointer to its element? Does big/little endian affect the result?

like image 470
Maluvel Avatar asked Jun 03 '14 08:06

Maluvel


People also ask

What is pointer to union in C?

union sample{ int a; float b; char c; }; union sample s; When union is declared, the compiler automatically creates largest size variable type to hold variables in the union. At any time only one variable can be referred. Same syntax of structure is used to access a union member.

How are pointers used in unions?

A pointer to a union can be cast to a pointer to each of its members (if a union has bit field members, the pointer to a union can be cast to the pointer to the bit field's underlying type). Likewise, a pointer to any member of a union can be cast to a pointer to the enclosing union.

Can we declare union pointer?

You can use any data type in a union, there's no restriction.

How is union declared?

Syntax for declaring a union is same as that of declaring a structure except the keyword struct. Note : Size of the union is the the size of its largest field because sufficient number of bytes must be reserved to store the largest sized field. To access the fields of a union, use dot(.)


2 Answers

void *ptr = &typevalue.value will do, because C standard (N1570, 6.7.2.1 Structure and union specifiers) says:

16 The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit- field, then to the unit in which it resides), and vice versa.

Address only makes sense in the current running environment (you don't store the address to flash), so endianness of address doesn't matter.

like image 130
user694733 Avatar answered Sep 30 '22 16:09

user694733


The three ideas are correct.

void *ptr = &(typevalue.value.u8value);
void *ptr = &(typevalue.value.s8value);
void *ptr = &(typevalue.value);

A union is a struct on memory that take the size of the larger type declared inside. All the fields use the same memory space, is just giving semantical information to the definition.

like image 20
chfumero Avatar answered Sep 30 '22 18:09

chfumero