Storing union values ​​in c

If we have a union with three variables int i, char c, float f; and we store the value of, say, the variable c. and we forget what constitutes a union variable, which after a while retains the value. there is some kind of mechanism provided by the language for which we can find out if it is me or c or f, which currently matters.

+1
source share
6 answers

It's impossible. Different members of the union all refer to the same memory address, these are just different ways to see this memory. Modifying a union member changes everything else. You cannot distinguish one from the other.

+3
source

Well, the point of union is that they will all matter. The value you are reading may not make sense if you are extracting a different type than you are inserting.

You need to keep track of what type you have nested if you are going to extract the same one. There is no language feature to track the situation for you.

+3
source
#define VARIANT_FLOAT_TYPE 1 #define VARIANT_DOUBLE_TYPE 2 // and so on struct variant_wb { union { float f; double d; int i; char c; }; int stored_type; }; 

Then you can use it as follows:

 struct variant_wb var; var.f = 1.23; var.stored_type = VARIANT_FLOAT_TYPE; 

You can also make unnecessary functions to work with this structure / union, or you could learn C ++ and do it β€œcorrectly”, because this language has this type of function. My C ++ is not very large, maybe some guru can show how to make such a decision, but in C ++.

+3
source

In C ++ / Qt / COM / DCOM there is the concept of "Variant", which roughly refers to the union, which also stores access to the connection. In C, you would have to provide something like this:

 struct myCVariant { int variantType; union { char v1; int v2; float v3; } variantContent; void initVariant() { variantType = 0; } void setChar(char a) { variantType = 1; variantContent.v1 = a; } void setInt(int a) { variantType = 2; variantContent.v2 = a; } // ... and so on bool getChar(char* pa) { if (variantType == 1) { *pa = variantContent.v1; return true; } return false; // Error reading a char where something else was stored } // ... and so on }; 

You can copy some Variant implementation into some C ++ source code and port it to C. This is not exactly the same, but similar. And this is somewhat typical (at least at runtime).

EDIT: hexa beat me for a second. And note that I did not compile this, so my code may contain typos.

+2
source

Not.

C is a lower level language. This allows you to write whatever you want for raw memory. After all, whether it contains text, integers, or code, all memory contains bits. There is no way to determine what these bits are.

As long as all members of the union keep the value, there is no mechanism to determine what type of data it was originally.

If you need to know this, then you must either save a flag indicating the data type or not use a union.

+1
source

Well, if you forget, because it will be written right here, and you can read it to find out.

+1
source

Source: https://habr.com/ru/post/891984/


All Articles