Thread: size of union without using sizeof operator

  1. #1
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59

    size of union without using sizeof operator

    Hi Everyone!
    I have written a code for it,it gives 2 warning messages but still gives the right answer.Can you share better ideas to implement for this concept.
    Code:
    #include<stdio.h>
    union size
    {
        int i;
        double d;
    }u[1];
    int main()
    {
        int res,a,b;
        a=u+0;
        b=u+1;
        res=b-a;
        printf("size of union=%d\n",res);
        return 0;
    }
    Tryin to store address in int var is the warning,but when I try to use pointers and implement,the difference between the addresses i given as 1 and not 8.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    How about
    int *a = &u[0].i;
    int *b = &u[1].i;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59
    Quote Originally Posted by Salem View Post
    How about
    int *a = &u[0].i;
    int *b = &u[1].i;
    Tried what you written,but's it's giving an answer as 2 instead of the 8.

  4. #4
    Registered User
    Join Date
    Aug 2012
    Posts
    41
    You should typecast a and b to int. Then you'll get answer as eight.

    Code:
        a=&u[0].i;
        b=&u[1].i;
        res=((int)b-(int)a);

  5. #5
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    Quote Originally Posted by shruthi View Post
    Hi Everyone!
    I have written a code for it,it gives 2 warning messages but still gives the right answer.Can you share better ideas to implement for this concept.
    Code:
    #include<stdio.h>
    union size
    {
        int i;
        double d;
    }u[1];
    int main()
    {
        int res,a,b;
        a=u+0;
        b=u+1;
        res=b-a;
        printf("size of union=%d\n",res);
        return 0;
    }
    Tryin to store address in int var is the warning,but when I try to use pointers and implement,the difference between the addresses i given as 1 and not 8.
    Even though this is a mostly pointless exercise, I think it would be better to cast the pointer to a pointer to char, not to int (int may not be big enough to hold a pointer, ie, sizeof(int) < sizeof(char *)):
    Code:
    char *a = (char *)&u[0];
    char *b = (char *)&u[1];
    int res = b - a;
    And you can obviously do the same without the intermediate variables "a" and "b":
    Code:
    int res = (char *)&u[1] - (char *)&u[0];

  6. #6
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    As long as you do only pointer arithmetic with the unions it should be safe.
    But otherwise you should have at least 2 instances of the union
    like
    Code:
    union size
    {
        int i;
        double d;
    }u[ 2 ];
    Kurt

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Actually, u[1] is sufficient.
    It is legal to have a pointer to the first element off the end of an array - but you can't dereference it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Salem View Post
    Actually, u[1] is sufficient.
    It is legal to have a pointer to the first element off the end of an array - but you can't dereference it.
    That's what I was trying to say.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    This exercise is pointless, since the compiler could not evaluate &u[0] and &u[1] (or &u[0].i and &u[0].i) without its own built-in knowledge of the value of sizeof(u). Not using the sizeof() keyword in code does not mean you are not making use of sizeof().

    Quote Originally Posted by Salem View Post
    How about
    int *a = &u[0].i;
    int *b = &u[1].i;
    Better to make the pointers of type char * rather than int, and use a type conversion to char *. No need to reference members of the union either. &u[0] is enough.

    When evaluating the difference between two pointers, better to use ptrdiff_t to get the difference. Then, if you must, convert that ptrdiff_t to another integral type for printing (printf()'s format modifiers to print a ptrdiff_t were not aware of ptrdiff_t in earlier versions of C). Less chance of overflowing an int that way, particularly on systems with pointers that are larger than an int.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    Quote Originally Posted by grumpy View Post
    When evaluating the difference between two pointers, better to use ptrdiff_t to get the difference. Then, if you must, convert that ptrdiff_t to another integral type for printing (printf()'s format modifiers to print a ptrdiff_t were not aware of ptrdiff_t in earlier versions of C). Less chance of overflowing an int that way, particularly on systems with pointers that are larger than an int.
    Then again, the size of the union in the example will (should?) always fit in an int, regardless of the size of pointers compared to the size of int, so storing the difference between pointers in an int variable (and printing that int) is fine in this case, IMO. But in the general case, ptrdiff_t is preferred over int.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by christop View Post
    Then again, the size of the union in the example will (should?) always fit in an int, regardless of the size of pointers compared to the size of int, so storing the difference between pointers in an int variable (and printing that int) is fine in this case, IMO
    Yeah, right. Only if you believe that all unions are small, like in the original example. It is very easy to construct a union (say, with one of its members is a large struct) that will produce a difference that cannot be represented by an int.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  12. #12
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    Quote Originally Posted by shruthi View Post
    Tryin to store address in int var is the warning,but when I try to use pointers and implement,the difference between the addresses i given as 1 and not 8.
    It gives you a 1 when you use pointers because when you do pointer arithmetic, it gives you results in units of the type size, not the size in bytes. which makes sense, because if you used pointers instead of ints for a and b,
    and you assign a = u+0 and b = u+1, and then subtract b-a, you get back what you added which is 1, not 8. it wouldn't make sense to if (u+1)-(u+0) == 8.

    as several folks said, casting to char * will give you the difference in bytes.

  13. #13
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I don't see what the problem is - "ptrdiff_t" is designed to hold a value equal to the difference between two pointers (the very thing that is trying to be achieved)

    It was created because "Existing types were deemed insufficient, because their size is defined according to the target processor's arithmetic capabilities, not the memory capabilities, such as available address space..."

  14. #14
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Click_here View Post
    I don't see what the problem is - "ptrdiff_t" is designed to hold a value equal to the difference between two pointers (the very thing that is trying to be achieved)

    It was created because "Existing types were deemed insufficient, because their size is defined according to the target processor's arithmetic capabilities, not the memory capabilities, such as available address space..."
    You seem to be quoting someone or something, but you haven't given your source. I'm assuming it's the Standard or the Rationale, but you should say so. Giving a link (if possible) is helpful, too.

    Question: If you want to print out a ptrdiff_t, what type do you cast it to? I assume a long. But if it is guaranteed to always fit into a long, what's the point of ptrdiff_t?
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Click_here View Post
    I don't see what the problem is - "ptrdiff_t" is designed to hold a value equal to the difference between two pointers (the very thing that is trying to be achieved)
    The problem is that some people insist on using int for such things, on the basis of something like "it works for this example, with my compiler". They then duck and weave (or simply refuse to respond) if someone uses their approach in a way that doesn't work.


    After all, an approach that works for some cases is just as good as an approach that works for all cases (within compiler limits) right?
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using sizeof on union
    By Edelweiss in forum C Programming
    Replies: 4
    Last Post: 08-18-2011, 08:13 AM
  2. Replies: 11
    Last Post: 07-27-2010, 08:43 AM
  3. Size of the UNION
    By BlackOps in forum C Programming
    Replies: 14
    Last Post: 07-11-2009, 04:29 PM
  4. sizeof union question
    By noops in forum C Programming
    Replies: 13
    Last Post: 06-06-2008, 11:56 AM
  5. Replies: 6
    Last Post: 10-15-2007, 08:05 AM