You are not logged in.

#1 2008-06-03 00:40:07

ConnorBehan
Package Maintainer (PM)
From: Long Island NY
Registered: 2007-07-05
Posts: 1,359
Website

Huge advantages to a union?

This is quite an amateur question but, I'm reading notes on C at this site http://www.cs.cf.ac.uk/Dave/C/node9.htm … 0000000000 and I'm on structs, unions, enums and typedefs right now. The one part that seemed relatively useless was the union.

I read up on it further and found out that unions only allocate enough memory to hold the largest member, and only one member is stored at a time. So if a union contains an integer, a char and a double, the size becomes 8 bytes (because of the double) and setting the integer to 69 automatically means the double member will be 69.0 and the char member will be "E" when referred to. I guess this means having two members with the same type in a union is utterly pointless.

I understand that, but isn't it the same as casting? Instead of creating a whole new part of the language (since C is supposed to be minimalistic) it would be rather easy to declare an int only and use (double) int or (char) int in place of the char and double members of the union used before. Some people told me casting is dangerous... but casting the basic types works whenever I do it, so to believe that I'd like to know a specific situation where casting would fail but not the use of a union.

The one advantage I have found so far is that a union allows the "casting" of user defined types.

#include <string.h>

struct pistol_struct
{
    char name[50];
    int magazinesize;
    float calibre;
};

struct rifle_struct
{
    char name[50];
    int magazinesize;
    float calibre;
};

typedef struct pistol_struct pistol;
typedef struct rifle_struct rifle;

main()
{
    rifle m_16 = {"M-16", 30, 0.45};
        pistol smaller_m_16 = (pistol) m_16;
        printf("%s, %d, %f", smaller_m_16.name, smaller_m_16.magazinesize, smaller_m_16.calibre);
}

That doesn't work... it complains that I'm trying to cast a non scalar type. However,

#include <string.h>

struct pistol_struct
{
    char name[50];
    int magazinesize;
    float calibre;
};

struct rifle_struct
{
    char name[50];
    int magazinesize;
    float calibre;
};

typedef struct pistol_struct pistol;
typedef struct rifle_struct rifle;

typedef struct gun_struct
{    
    union {
        pistol pistol_type;
        rifle rifle_type;
    } gun_type;
} gun;

main()
{
    gun example;
    rifle m_16 = {"M-16", 30, 0.45};
    
    example.gun_type.rifle_type = m_16;
    
    printf("%s %d %f\n", example.gun_type.pistol_type.name, example.gun_type.pistol_type.magazinesize, example.gun_type.pistol_type.calibre);
}

that does work, it is able to accept what was once a "rifle" type as a "pistol". Is there any other reason why we should all use unions?


6EA3 F3F3 B908 2632 A9CB E931 D53A 0445 B47A 0DAB
Great things come in tar.xz packages.

Offline

#2 2008-06-03 00:48:05

rizzix
Member
Registered: 2005-10-22
Posts: 55

Re: Huge advantages to a union?

A cast of the form a = (type) b, could possibly create a temporary (casted to type) object on the stack. On the other hand a union guarantees that a fixed amount of memory will be allocated.

General tips:
Never cast, unless absolutely necessary and you know the side-effects of a cast.
Never use unions, unless you absolutely have a need to use them -- e.g. for memory sensitive applications.

Last edited by rizzix (2008-06-03 00:54:07)

Offline

#3 2008-06-03 01:53:12

nj
Member
Registered: 2007-04-06
Posts: 93

Re: Huge advantages to a union?

ConnorBehan wrote:

I read up on it further and found out that unions only allocate enough memory to hold the largest member, and only one member is stored at a time. So if a union contains an integer, a char and a double, the size becomes 8 bytes (because of the double) and setting the integer to 69 automatically means the double member will be 69.0 and the char member will be "E" when referred to.

Not exactly. When you set the integer to 69, the bits of the memory get set for an integer 69. If you then try to print the double portion of the union, it will not be 69.0 because the double type interprets the bits in a different format (search for 'ieee float' for more info). If you cast a int into double, the processor will actually perform a computation to convert from one format to the other. See the code below for an example.

#include <stdio.h>

int main()
{
    union {
        char c;
        int i;
        double d;
    } blah;

    blah.i = 69;

    printf("%d\n", blah.i);
    printf("%c\n", blah.c);
    printf("%f %f\n", (double)blah.i, blah.d);

    return 0;
}

$ gcc union.c
$ ./a.out
69
E
69.000000 -0.000000

You will not encounter unions much. I would not worry about them.

Offline

#4 2008-06-03 16:13:13

ConnorBehan
Package Maintainer (PM)
From: Long Island NY
Registered: 2007-07-05
Posts: 1,359
Website

Re: Huge advantages to a union?

Ah, so I'm still better off to cast for converting between the basic types. When taking the sqrt of an integer or dividing 3 by 2 hoping to get 1.5, I need to cast the integer as a float or a double or something. Is this generally safe to do if the computer running the program has heaps of spare memory? If not, would a safer way be to use a function for converting types? Like atoi except inttodouble if there is such a function.


6EA3 F3F3 B908 2632 A9CB E931 D53A 0445 B47A 0DAB
Great things come in tar.xz packages.

Offline

#5 2008-06-03 16:35:06

toofishes
Developer
From: Chicago, IL
Registered: 2006-06-06
Posts: 602
Website

Re: Huge advantages to a union?

ConnorBehan wrote:

This is quite an amateur question but, I'm reading notes on C at this site http://www.cs.cf.ac.uk/Dave/C/node9.htm … 0000000000 and I'm on structs, unions, enums and typedefs right now. The one part that seemed relatively useless was the union.

I read up on it further and found out that unions only allocate enough memory to hold the largest member, and only one member is stored at a time. So if a union contains an integer, a char and a double, the size becomes 8 bytes (because of the double) and setting the integer to 69 automatically means the double member will be 69.0 and the char member will be "E" when referred to. I guess this means having two members with the same type in a union is utterly pointless.

I understand that, but isn't it the same as casting? Instead of creating a whole new part of the language (since C is supposed to be minimalistic) it would be rather easy to declare an int only and use (double) int or (char) int in place of the char and double members of the union used before. Some people told me casting is dangerous... but casting the basic types works whenever I do it, so to believe that I'd like to know a specific situation where casting would fail but not the use of a union.

The original purpose of the union I believe (no backing source here) was saving memory. If a programmer knew only one member of a struct or another would be in use, then you could wrap these inside a union so the struct would have a smaller memory footprint.

This was useful when every byte mattered on machines that have < 1MB of memory, but that just isn't the case anymore so the union is not all that useful. You would need to have a real compelling reason to use it, and casting is not at all what it is for.

Offline

#6 2008-06-04 16:22:34

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: Huge advantages to a union?

If you sometimes want to access the individual bytes of a uint32, the simplest way I know is to do a

union {
  uint32 int;
  char bytes[4];
} uint_bytes;

What a union offers, is multiple ways of accessing (parts of) the same memory.

Last edited by gnud (2008-06-04 16:22:58)

Offline

#7 2008-06-04 16:44:33

usr
Member
Registered: 2006-07-26
Posts: 20

Re: Huge advantages to a union?

I've used a union for converting two bytes into an int (16 bit) and back again for sending by serial links on a microcontroller as it seemed like the easiest way. Store the int and then send byte one then byte two or read two bytes and return the int. It saved memory and looked a bit neater than using pointers (which I still haven't got the hang of yet).


Do you ever get that "Oops" feeling?

Offline

#8 2008-06-04 17:57:03

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: Huge advantages to a union?

Yeah, the main uses have been covered.

1) Say you have a struct that can be in two states, with different information available in each state.  Then, this would make sense to conserve memory:

struct myStruct {
    char active; // boolean: 0=inactive, 1=active
    union {
        struct {
            ... // data pertaining to inactive state
        } inactiveData;
        struct {
            ... // data pertaining to active state
        } activeData;
    } data;
};

2) Multiple ways to access the same data.  I've seen something like this before:

struct statBin {
  union {
    uint64_t data;
    struct {
      uint16_t bytes_tx;
      uint16_t bytes_rx;
      uint8_t pkts_rx;
      uint8_t pkts_tx;
      uint8_t connections;
      uint8_t active_connections;
    } itemizedStats;
  } stats;
  // other data here
};

// clear the given bin
void clearStats(struct statBin * myStats)
{
    // quicker than accessing each individual member
    myStats->stats.data = 0;
}

void logNewConnection(struct statBin * myStats)
{
    ++myStats->stats.itemizedStats.connections;
    ++myStats->stats.itemizedStats.active_connections;
}

void logDisconnection(struct statBin * myStats)
{
    --myStats->stats.itemizedStats.active_connections;
}

Offline

#9 2008-06-05 03:14:18

ConnorBehan
Package Maintainer (PM)
From: Long Island NY
Registered: 2007-07-05
Posts: 1,359
Website

Re: Huge advantages to a union?

The simple programs I'm making now don't have much use for unions but it will be cool if I can work them into programs I make later... if it helps make them efficient in some small way.

I've grep'd through a few program source directories that I have saved and I usually only find 1 or 2 unions per megabyte of source. It's funny how when these notes were written, C didn't have booleans which are so widely used, yet C had something as specialized as a union.


6EA3 F3F3 B908 2632 A9CB E931 D53A 0445 B47A 0DAB
Great things come in tar.xz packages.

Offline

#10 2008-06-05 05:20:29

toofishes
Developer
From: Chicago, IL
Registered: 2006-06-06
Posts: 602
Website

Re: Huge advantages to a union?

The pacman codebase actually does use a union:
http://projects.archlinux.org/?p=pacman … b=HEAD#l64
in case you were curious enough to see one in action, and it is even commented.

Offline

#11 2008-06-06 08:11:41

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: Huge advantages to a union?

A union is not really specialized -- earlier it was _nessescary_ to pack as much information as possible into each (16 or 32 bit) processor register. Assembly programmers wouldn't use more memory then they had to, and C makes this manageable in a higher level language too.

Nowadays, most programs waste some hundred bytes of memory by not packing structs and not using unions. But when a simple home computer has 1GB of ram or more, it doesn't really matter.

Offline

Board footer

Powered by FluxBB