properly using unions.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pereges

    properly using unions.

    Hello, can some one please guide me a little into using unions. I read
    about unions in K & R but I am finding it difficult to apply to my
    problem at hand. I want to save up some space by using unions . My
    questions are :

    1. Is it dangerous to use unions ? Is it worth the trouble if I want
    to save memory ? Are they error prone ?

    2. I read that it is not possible to access more than 1 member at any
    instant from a union. What does this actually mean ? I cannot use two
    members simultaneously in a single statement ?

  • Richard Heathfield

    #2
    Re: properly using unions.

    pereges said:
    Hello, can some one please guide me a little into using unions. I read
    about unions in K & R but I am finding it difficult to apply to my
    problem at hand. I want to save up some space by using unions . My
    questions are :
    >
    1. Is it dangerous to use unions ?
    No, not if you know what you're doing.
    Is it worth the trouble if I want to save memory ?
    Probably not, unless you're really really really memory-starved.
    Are they error prone ?
    No, but programmers are. :-)
    2. I read that it is not possible to access more than 1 member at any
    instant from a union. What does this actually mean ? I cannot use two
    members simultaneously in a single statement ?
    Let's say you're using a union to store a nine-byte object and an
    eleven-byter. The union will probably be eleven bytes wide - i.e. wide
    enough to store the biggest thing you're putting in it - but it might be a
    little bit wider for alignment reasons, e.g. twelve (multiple of 4) or
    even sixteen (multiple of 16) bytes. But 11+9 is 20, and it's pretty
    unlikely to be that big. In any case, you can only legitimately access the
    first eleven bytes.

    Now, eleven bytes is plenty big enough to store a nine-byte object, or even
    an eleven-byte object. But it isn't big enough to store both.

    So at any one point, that union can only be storing one value or the other,
    right? It can't store both. So how could it possibly make sense to try to
    use both values at the same time? There is no "both values" to use! There
    is only one value. It might be this one or it might be that one, depending
    on what you shoved in there last, but it can't possibly be both.

    --
    Richard Heathfield <http://www.cpax.org.uk >
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999

    Comment

    • rahul

      #3
      Re: properly using unions.

      On Jun 25, 11:34 am, pereges <Brol...@gmail. comwrote:
      Hello, can some one please guide me a little into using unions. I read
      about unions in K & R but I am finding it difficult to apply to my
      problem at hand. I want to save up some space by using unions .
      Unions aren't generally about saving space. They are used in a
      situation in which you don't use all the members but access them based
      on some condition.

      My
      questions are :
      >
      1. Is it dangerous to use unions ? Is it worth the trouble if I want
      to save memory ? Are they error prone ?
      If it's about saving memory, I am afraid its going to a lot of trouble
      and it's not worth it.

      2. I read that it is not possible to access more than 1 member at any
      instant from a union. What does this actually mean ? I cannot use two
      members simultaneously in a single statement ?
      In an union, the space allocated equals the size of biggest member
      (and any padding done by the implementation) .
      union _foo {
      int bar;
      double baz;
      }foo;

      sizeof(union foo) will give you sizeof(double) and maybe some padding.
      Both bar and baz share the same memory space. They are distinct
      members but they share the same memory space.

      Consider :

      #define DOUBLE 1
      #define STRING 2
      #define INT 3

      struct _node {
      int type;
      union {
      double d;
      char a[10];
      int i;
      }
      _node *next;
      }node;
      struct node *list;

      /* ... */
      void *getElement(voi d) {
      switch (list->type) {
      case DOUBLE:
      return &(list->d);
      case STRING:
      return list->a;
      case INT:
      return &(list->i);
      default:
      return null;
      }

      This is just a skeleton. In this scenario, you are using unions to
      have a hetrogenous list. There are some other scenarios but I don't
      think its worth playing tricks with unions just to save space.

      Comment

      • santosh

        #4
        Re: properly using unions.

        rahul wrote:

        <snip>
        In an union, the space allocated equals the size of biggest member
        (and any padding done by the implementation) .
        union _foo {
        int bar;
        double baz;
        }foo;
        >
        sizeof(union foo) will give you sizeof(double) and maybe some padding.
        Correct me if I'm wrong, but isn't it perfectly conforming for an
        implementation to have sizeof(int) sizeof(double)?

        <snip>

        Comment

        • rahul

          #5
          Re: properly using unions.

          On Jun 25, 1:22 pm, santosh <santosh....@gm ail.comwrote:
          rahul wrote:
          >
          Correct me if I'm wrong,
          You are not.
          but isn't it perfectly conforming for an
          implementation to have sizeof(int) sizeof(double)?
          It is perfectly conforming for an implementation to have sizeof(int) >
          sizeof(double).


          >
          In an union, the space allocated equals the size of biggest member
          (and any padding done by the implementation) .
          union _foo {
          int bar;
          double baz;
          }foo;
          >
          sizeof(union foo) will give you sizeof(double) and maybe some padding.
          Correction:
          sizeof(union foo) wil give you whatever is greater of sizeof(int) and
          sizeof(double) and padding, if any.

          Comment

          • Chris Dollin

            #6
            Re: properly using unions.

            rahul wrote:
            Unions aren't generally about saving space. They are used in a
            situation in which you don't use all the members but access them based
            on some condition.
            There seem to be two ways of using unions.

            One is type-punning, where you write a value into on member of
            the union and read it from another with a different type. This
            is useful much less often than one might suppose, because the
            Standard leaves undefined rather a lot of possibilities. The
            wise man will often go another way.

            The other way is when the union is expressing the idea that the
            desired value is either this, or that, or the other, and which
            it is, is "based on some condition". In this case, it seems to
            me that the union /is/ about saving space, since otherwise you
            could equally well use a struct.

            --
            "Its deductive method was holistic, totalising, /Perdido Street Station/
            and inconstant."

            Hewlett-Packard Limited registered office: Cain Road, Bracknell,
            registered no: 690597 England Berks RG12 1HN

            Comment

            • Johannes Bauer

              #7
              Re: properly using unions.

              rahul schrieb:
              In an union, the space allocated equals the size of biggest member
              (and any padding done by the implementation) .
              Please quote from the standard as I do not think this is true.

              Lets say we have a union x

              union x {
              int foo;
              double bar;
              };

              then the following is okay:

              x.foo = 4;
              printf("%d\n", x.foo);
              x.bar = 3.1415;
              printf("%lf\n", x.bar);

              But this is not

              x.foo = 4
              printf("%lf\n", x.bar);

              As only one member is valid to be read which has been written. The
              standard would not say that IMHO if it were not possible for an
              implementation to just concatenate the elements, i.e. making a union
              equal to a struct.

              Regards,
              Johannes

              --
              "Wer etwas kritisiert muss es noch lange nicht selber besser können. Es
              reicht zu wissen, daß andere es besser können und andere es auch
              besser machen um einen Vergleich zu bringen." - Wolfgang Gerber
              in de.sci.electron ics <47fa8447$0$115 45$9b622d9e@new s.freenet.de>

              Comment

              • Richard Tobin

                #8
                Re: properly using unions.

                In article <dif9j5x2e9.ln2 @joeserver.home lan.net>,
                Johannes Bauer <dfnsonfsduifb@ gmx.dewrote:
                >As only one member is valid to be read which has been written. The
                >standard would not say that IMHO if it were not possible for an
                >implementati on to just concatenate the elements, i.e. making a union
                >equal to a struct.
                But it does. C99 6.7.2.1: "The size of a union is sufficient to contain
                the largest of its members ... A pointer to a union object, suitably
                converted, points to each of its members".

                -- Richard
                --
                In the selection of the two characters immediately succeeding the numeral 9,
                consideration shall be given to their replacement by the graphics 10 and 11 to
                facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)

                Comment

                • ediebur@rcn.com

                  #9
                  Re: properly using unions.

                  On Jun 25, 2:34 am, pereges <Brol...@gmail. comwrote:
                  Hello, can some one please guide me a little into using unions. I read
                  about unions in K & R but I am finding it difficult to apply to my
                  problem at hand. I want to save up some space by using unions . My
                  questions are :
                  >
                  1. Is it dangerous to use unions ? Is it worth the trouble if I want
                  to save memory ? Are they error prone ?
                  >
                  2. I read that it is not possible to access more than 1 member at any
                  instant from a union. What does this actually mean ? I cannot use two
                  members simultaneously in a single statement ?
                  I have lots of experience C programming ( although not recent -- I
                  hope things haven't changed that much) and to me, clarity was always a
                  priority. I guess I was never in a memory starved environment ( well,
                  I did have to use overlays in a PDP 11). I never saw a use for unions.
                  Except for type punning-- something I was aware of but never had to
                  use.

                  Comment

                  • Bartc

                    #10
                    Re: properly using unions.

                    ediebur@rcn.com wrote:
                    On Jun 25, 2:34 am, pereges <Brol...@gmail. comwrote:
                    >Hello, can some one please guide me a little into using unions. I
                    >read about unions in K & R but I am finding it difficult to apply to
                    >my problem at hand. I want to save up some space by using unions . My
                    >questions are :
                    >>
                    >1. Is it dangerous to use unions ? Is it worth the trouble if I want
                    >to save memory ? Are they error prone ?
                    >>
                    >2. I read that it is not possible to access more than 1 member at any
                    >instant from a union. What does this actually mean ? I cannot use two
                    >members simultaneously in a single statement ?
                    >
                    I have lots of experience C programming ( although not recent -- I
                    hope things haven't changed that much) and to me, clarity was always a
                    priority. I guess I was never in a memory starved environment ( well,
                    I did have to use overlays in a PDP 11). I never saw a use for unions.
                    Except for type punning-- something I was aware of but never had to
                    use.
                    You haven't lived. I have used the following struct with unions, and even
                    then I have to rely on half-a-dozen helper macros to get the variable field
                    accesses I need. This struct is 16 bytes but looks bigger:

                    typedef struct svarrec {
                    short int dtype; /* These 4 bytes also accessed as int using asint()
                    */
                    char copy;
                    char spare;

                    union { /* .value */
                    int value;
                    int xvalue; /* use asreal() to access .xvalue/.xvalue2 together
                    */
                    int dvalue; /* use asint64() to access .dvalue/.dvalue2 together
                    */
                    char *svalue;
                    char *ptr;
                    struct svarrec *vptr;
                    int *retaddr;
                    int first;
                    };

                    union { /* .value2 */
                    int value2;
                    int length;
                    int upper;
                    int frame;
                    int last;
                    int xvalue2; /* top half of double at .xvalue */
                    int dvalue2; /* top half of int64 at .dvalue */
                    short int rdoti;
                    short int rlength; /* in msw, use asmsw() macro */
                    };

                    union { /* .value3 */
                    int value3;
                    int lower;
                    int tag;
                    int pos;
                    int doti;
                    int nvars;
                    short int elemtype;
                    short int shortlower; /* in msw, use asmsw() macro */
                    };

                    } varrec;

                    (Note: this makes use of anonymous unions, which I think is not standard.
                    Using named unions would really obfuscate the code with extraneous field
                    names.)

                    --
                    Bartc



                    Comment

                    • CBFalconer

                      #11
                      Re: properly using unions.

                      ediebur@rcn.com wrote:
                      >
                      .... snip ...
                      >
                      I have lots of experience C programming ( although not recent --
                      I hope things haven't changed that much) and to me, clarity was
                      always a priority. I guess I was never in a memory starved
                      environment (well, I did have to use overlays in a PDP 11). I
                      never saw a use for unions. Except for type punning-- something
                      I was aware of but never had to use.
                      You obviously never wrote any compilers.

                      --
                      [mail]: Chuck F (cbfalconer at maineline dot net)
                      [page]: <http://cbfalconer.home .att.net>
                      Try the download section.

                      ** Posted from http://www.teranews.com **

                      Comment

                      • Johannes Bauer

                        #12
                        Re: properly using unions.

                        Richard Tobin schrieb:
                        In article <dif9j5x2e9.ln2 @joeserver.home lan.net>,
                        Johannes Bauer <dfnsonfsduifb@ gmx.dewrote:
                        >
                        >As only one member is valid to be read which has been written. The
                        >standard would not say that IMHO if it were not possible for an
                        >implementati on to just concatenate the elements, i.e. making a union
                        >equal to a struct.
                        >
                        But it does. C99 6.7.2.1: "The size of a union is sufficient to contain
                        the largest of its members ... A pointer to a union object, suitably
                        converted, points to each of its members".
                        Sufficient means at least as large as the largest member, so no hint
                        there. But the second constraint means that all objects within the union
                        have to start in the same memory region - so that's something one cannot
                        argue with. The use of a struct instead of a union by the compiler is
                        therefore definitely forbidden.

                        Thanks for the pointer.

                        Regards,
                        Johannes

                        --
                        "Wer etwas kritisiert muss es noch lange nicht selber besser können. Es
                        reicht zu wissen, daß andere es besser können und andere es auch
                        besser machen um einen Vergleich zu bringen." - Wolfgang Gerber
                        in de.sci.electron ics <47fa8447$0$115 45$9b622d9e@new s.freenet.de>

                        Comment

                        Working...