Thread: Having a problem with unions...

  1. #1
    Registered User
    Join Date
    Jun 2007
    Posts
    4

    Question Having a problem with unions...

    This is a slightly revamped version of a program some you guys helped me with last night. It turns out that it didn't meet the requirements, but this should if I can get it to work:
    Code:
    #include <stdio.h>
    typedef  enum {now=10, next, last} grade;
    union {int age; float exactage;} age;
    
    main()
    {
      struct {char first_name[20]; char last_name[20];} info;
      int grade = now;
      union age my;
      my.exactage=15.731506849;
    
      strcpy(info.first_name, "name");
      strcpy(info.last_name, "name");
     
     printf("This program is by %s %s. His exact age is %f, his approximate age is %d. He is currently is grade %d.", info.first_name, info.last_name, my.exactage, my.age, now);
    }
    error: "aggregate 'union age my' has incomplete type and cannot be initialized"

    I've always had problems with unions, so odds are I've made at least one huge mistake. Any and all help would be appreciated.

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    *sighs*

    Code:
    union {int age; float exactage;} age;
    This declares an anonymous union and creates one instance of it called age.

    Code:
    union age my;
    This allocates memory for one union named age and names the instance of it my.

    If you have an anonymous union, you can't allocate instances of it. One solution is to change your union definition:

    Code:
    union age {int age; float exactage;};
    Edit: BTW, what you're doing is incorrect anyway. Unions are like structs except all members are located at the same position in memory. That means if you edit one member, you edit the others as well. Floating point numbers are usually represented in binary totally different than integer numbers. The interpretation of these numbers is, again, very different.

    For example, I ran your program, and got this:

    This program is by name name. His exact age is 15.731507, his approximate age is 1098626113. He is currently is grade 10.
    See what I mean?
    Last edited by MacGyver; 06-23-2007 at 11:10 PM.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Posts
    4
    Thanks. I did that, changed the name of the union to 'ages', and now it works!

    EDIT: Yeah, I also got that. I just made them both floats. Entirely pointless, but it works.
    EDIT 2: I also changed the sentence, so it still (kind of) makes sense.
    Last edited by imalumberjak; 06-23-2007 at 11:18 PM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You're having more than one problem.

    Firstly, union declarations are of the form;
    Code:
    union optional_type_name
    {
        /*  contained variables
    }
    optional_variable_name_1, optional_variable_name_2;   /* etc */
    which means that, in your case, your union declaration should be;
    Code:
    union age {int age; double exactage;};
    so that later declarations of your variable "my" will work.

    The second problem is that unions can't be used to convert a double to an int in the way you're expecting. In particular, the line;
    Code:
        my.exactage = 15.731506849;
    does not implicitly cause my.age to have a value of 15. The actual value of my.age could be anything: it depends on the actual layout, in memory, of int and double types.

    To convert a double to an int, with rounding down, a correct approach is to use mathematical operations without a union in sight. For example;
    Code:
    #include <math.h>
    #include <stdio.h>
    
    int main()
    {
        double exactage = 15.731506849;
        int age = (int)(floor(exactage));
        printf("Exact age is &#37;f and his number of birthdays is %d\n", exactage, age);
    }

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318

    Wink

    Just forget unions exist for now. There shouldn't be a single 'union' within ten feet of that code.
    'struct' is what you're after!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Not even a struct. Just keep exact-age, which you can always display as an integer if you want to.

    By the way, are ages even mathematically rounded or just truncated? I don't add one to my age half a year before my birthday...
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by anon View Post
    Not even a struct. Just keep exact-age, which you can always display as an integer if you want to.

    By the way, are ages even mathematically rounded or just truncated? I don't add one to my age half a year before my birthday...
    I walked into a bar when I was 20 years and 9 months old, and tried that line of reasoning: "My age rounds up to 21, see?"

    Didn't fly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM