LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C (++) Unions trouble (https://www.linuxquestions.org/questions/programming-9/c-unions-trouble-806793/)

rajitsingh 05-09-2010 10:38 AM

C (++) Unions trouble
 
Just playin around, i created this union:

Code:

union name1{
        int i;
        float f;
        double d;
};
int main(){
        name1 n1;
        n1.f=2.32;
        cout<<"n1.f= "<<n1.i<<endl;  \\case 1, returns garbage
        cout<<"n1.f= "<<n1.f<<endl;  \\case 2
        cout<<"n1.f= "<<n1.d<<endl;  \\case 3, returns garbage
        return 0;
}

Now, if all the members of a union share the same memory space, then why do 'case 1' and 'case 3' return garbage values?
I thought it would be so with 'case 1' because of narrowing, but what about 'case 3'??

graemef 05-09-2010 11:03 AM

because you assigned garbage in. (From the perspective of an integer)

ForzaItalia2006 05-09-2010 11:53 AM

Quote:

Originally Posted by rajitsingh (Post 3962212)
Code:

union name1{
        int i;
        float f;
        double d;
};
int main(){
        name1 n1;
        n1.f=2.32;
        cout<<"n1.f= "<<n1.i<<endl;  \\case 1, returns garbage
        cout<<"n1.f= "<<n1.f<<endl;  \\case 2
        cout<<"n1.f= "<<n1.d<<endl;  \\case 3, returns garbage
        return 0;
}


It depends on what you consider as garbage :-) To give you a bit of more context than graemef although he's totally correct!

Because you might not now all the details of how floating point numbers are represented in binary mode (IEEE specification), I'll try to explain this using plain integer types. Assume you have a union with two members, having integer (32-bit) and short (16-bit) types, whereby both obviously overlap in memory.

The 16-bit short member covers the low/high (depending on the endianess) 16-bit of the integer type. Though, say you set the integer to 0x00001234 on a little-endian system, then the short will have the value of 0x1234. On a big-endian system however, the short value will be 0x0000.

Though, the memory region pointed to by a union is interpreted according to the type by which this memory region is accessed.

I hope that somehow helps to understand why your app produces garbage for the cases 1 and 3.

- Andi -

ArthurSittler 05-09-2010 05:47 PM

please don't violate type in unions
 
Unions are not provided as a method to circumvent the type protections of the C language. You are trying to use unions in a way that is prohibited by the semantics of the language, though the compiler will not and actually can not prohibit the violation.

Using unions is actually deprecated in C++. C++ adopts the syntax, grammar, and semantics of C. That is why it was named C++ and not something completely different, such as "Objectiva". C++ grudgingly provides unions to support the principle that a good C program is an acceptable C++ program. There are well written C programs that employ unions, but those programs do not abuse unions as you were attempting to do. C++ provides inheritance and polymorphism to provide equivalent functionality.

You should not be surprised that you can not read back a union in a type different from the type that was last written to the union. The documentation of the C programming language states explicitly that it is the programmer's responsibility to keep track of what type was last written to the union and only read back the type last written to the union. A union may be initialized when it is defined only as the first member type.

You should not attempt to use a union to manipulate or convert the union member to a different type. There are casts and library functions for that purpose. The format of data in unions is explicitly implementation dependent in the C language. This means that even if you can glean information about the format of one data type by looking it as a different data type, that information may not be portable to any other compiler or any other machine architecture. In fact, it may not be portable even to a later or earlier version of the same compiler on the same machine architecture.

If you would like to examine the format of different types of data, you may be able to do so in a debugger which displays the binary representation of the data in hex format. Don't count on the format of that type of data to be the same in any other context.

rajitsingh 05-10-2010 05:37 AM

Are you all trying to say that it could be because different types are represented using different representations in memory, and the garbage is produced when i try to read a given representation using a different interpretation?

johnsfine 05-10-2010 06:59 AM

Quote:

Originally Posted by rajitsingh (Post 3963119)
Are you all trying to say that it could be because different types are represented using different representations in memory, and the garbage is produced when i try to read a given representation using a different interpretation?

Change "could be" to "is" and you have your answer.

I do not mean that any two different data types necessarily have different representations. In some architectures, int and long have the same representation. It is less common, but in some architectures float and double have the same representation (as each other, not same as int or long).

I mean that when an operation on a union, such as the one you did, produces garbage that is because the representation is different.

ArthurSittler 05-10-2010 07:14 AM

Different type data has different representation in memory
 
Yes, that is the case. You description is much better and more concise than my somewhat rambling explanation.

The representation we use for things that we simply count (integers) does not apply as aptly to quantities that we measure (floats). Though we could estimate the number of water molecules in a glass of water, we could not in fact count them. We assign an integer identification number to each record in a database because there can not be an arbitrarily small part of a record. And neither integer nor float format would be a very good method for storing the text of this message.

All information stored by computers is represented as binary numbers of possibly different numbers of bits, depending on the type of object we want to represent. Even in objects represented by the same number of bits, the meaning of the bits differ when they represent different types of objects.

graemef 05-10-2010 10:16 AM

You might want to take a look at this wikipedia page on floating point.Specifically look at the section on general layout. Then have a gander at this page on Signed number representations.

So yes the internal representation depends upon the data type. Different operating systems, computer architecture, programming language (take your pick) may also vary the internal representation. I hope these links help.

rajitsingh 05-10-2010 02:52 PM

Thanks everyone, I get it now.


All times are GMT -5. The time now is 07:16 PM.