64 bit Endianness issue

Discussion in 'C Programming' started by sureshjayaram@gmail.com, May 11, 2006.

  1. Guest

    I have problem with the code only with 64 bit big endian machine.
    i have a member size_t val1 in my structure. The size of size_t is
    32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    machines.

    I am passing address of this variable to a different function (where it
    accepts only pointer to unsigned int) unsigned int *. Basically passing
    a unsigned long pointer instead of unsigned int pointer. I think the
    value is getting truncated while dereferencing int *. In this case how
    do I make my code portable? Can functions like htonl/ntohl will help?
    or casting could be of any help?

    Thanks,
    Suresh
     
    , May 11, 2006
    #1
    1. Advertising

  2. In article <>,
    <> wrote:
    >I have problem with the code only with 64 bit big endian machine.
    >i have a member size_t val1 in my structure. The size of size_t is
    >32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >machines.


    >I am passing address of this variable to a different function (where it
    >accepts only pointer to unsigned int) unsigned int *. Basically passing
    >a unsigned long pointer instead of unsigned int pointer. I think the
    >value is getting truncated while dereferencing int *. In this case how
    >do I make my code portable?


    On the 64 bit machines, can the values to be stored in the structure
    member legitimately exceed 32 bits? If they can, then chances
    are your only choice is to rewrite the other function. There is
    nothing you can do to "remotely" force another routine to operate on
    more bits than it was coded for.
    --
    All is vanity. -- Ecclesiastes
     
    Walter Roberson, May 11, 2006
    #2
    1. Advertising

  3. wrote:
    > I have problem with the code only with 64 bit big endian machine.
    > i have a member size_t val1 in my structure. The size of size_t is
    > 32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    > machines.
    >
    > I am passing address of this variable to a different function (where it
    > accepts only pointer to unsigned int) unsigned int *. Basically passing
    > a unsigned long pointer instead of unsigned int pointer. I think the
    > value is getting truncated while dereferencing int *. In this case how
    > do I make my code portable? Can functions like htonl/ntohl will help?
    > or casting could be of any help?
    >
    > Thanks,
    > Suresh


    Do the circumstances allow the following?

    struct {
    size_t val1;
    } my_struct;
    int tmp = 0;
    some_function_that_takes_a_pointer_to_an_int(&tmp);
    if (tmp < 0) /* do something */ ;
    my_struct.val1 = tmp;

    I assume some_function_that_takes_a_pointer_to_an_int() will be
    dereferencing the pointer passed to it later. In this case you still
    have some options, but it depends on how you are going to be using the
    structure.

    Charlie
     
    Charles Mills, May 11, 2006
    #3
  4. Guest

    It's like..

    struct {
    size_t val1; // can be unsigned long in 64 bit
    } my_struct;
    struct my_struct val;

    func(&val.val1);

    void func(unsigned int *)
    {
    // val1 can be deferenced
    }

    Is there workaround in case of 64bit?
     
    , May 12, 2006
    #4
  5. Ian Collins Guest

    wrote:
    > It's like..
    >

    What's like? Please quote what you are replying to, see
    <http://cfaj.freeshell.org/google/>.

    > struct {
    > size_t val1; // can be unsigned long in 64 bit
    > } my_struct;
    > struct my_struct val;
    >
    > func(&val.val1);
    >
    > void func(unsigned int *)
    > {
    > // val1 can be deferenced
    > }
    >
    > Is there workaround in case of 64bit?
    >

    You should get a diagnostic as you are passing a pointer to an
    incompatible type.

    --
    Ian Collins.
     
    Ian Collins, May 12, 2006
    #5
  6. Guest

    Iam getting warning message only in 64bit m/c warning: passing argument
    ... from incompatible pointer type
    How to solve this?
     
    , May 12, 2006
    #6
  7. Ian Collins Guest

    wrote:
    > Iam getting warning message only in 64bit m/c warning: passing argument
    > ... from incompatible pointer type
    > How to solve this?
    >

    Solve what? I asked you politely to quote context. If you don't want
    to help me, I won't help you.

    --
    Ian Collins.
     
    Ian Collins, May 12, 2006
    #7
  8. Guest

    Sorry I did't notice the first part of the previous message. I should
    have provided the context in the first place.

    I have problem with the code only with 64 bit big endian machine.
    i have a member size_t val1 in my structure. The size of size_t is
    32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    machines.

    I am passing address of this variable to a different function (where it

    accepts only pointer to unsigned int) unsigned int *. Basically passing

    a unsigned long pointer instead of unsigned int pointer. I think the
    value is getting truncated while dereferencing int *. In this case how
    do I make my code portable? Can functions like htonl/ntohl will help?
    or casting could be of any help?

    struct {
    size_t val1; // can be unsigned long in 64 bit
    } my_struct;
    struct my_struct val;

    func(&val.val1);

    void func(unsigned int *val1)
    {
    // val1 can be deferenced here
    }

    When I dereference I will be getting only the truncated 32 bits which
    is giving wrong value.

    The below example when run on 3 different arch (i386, ia64 & s390x)
    provided different output which confirms the same

    #include <stdio.h>

    int main()
    {
    size_t i = 1524;
    unsigned int *k = &i;

    printf("i is %d\n*k is %d\n", i, *k);
    }

    On i386
    1524
    1524

    on ia64
    1524
    1524

    on s390x (big endian)
    1524
    0
     
    , May 12, 2006
    #8
  9. >I have problem with the code only with 64 bit big endian machine.
    >i have a member size_t val1 in my structure.


    >The size of size_t is
    >32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >machines.


    I'm not convinced this generalization is valid for all 32-bit or
    64-bit machines.

    >I am passing address of this variable to a different function (where it
    >
    >accepts only pointer to unsigned int) unsigned int *.


    This is your problem. Fix it. There are several approaches:

    (1) Fix the function to accept a pointer to size_t.
    (2) Copy the size_t into an unsigned int (by assignment), and pass a
    pointer to *THAT*. If the function might change the value pointed
    at, copy it back afterwards. However, you're going to have trouble
    if the value won't FIT in an unsigned int, which itself presents problems.
    (3) Change the type of the member to unsigned int.

    >Basically passing
    >a unsigned long pointer instead of unsigned int pointer. I think the
    >value is getting truncated while dereferencing int *. In this case how
    >do I make my code portable?


    Fix the type mismatch so the types no longer mismatch.

    >Can functions like htonl/ntohl will help?

    No.

    >or casting could be of any help?


    Casting of *pointers* won't help here. Casting of values
    might, but that's not what you are passing.

    Gordon L. Burditt
     
    Gordon Burditt, May 12, 2006
    #9
  10. Ian Collins Guest

    Gordon Burditt wrote:
    >>I have problem with the code only with 64 bit big endian machine.
    >>i have a member size_t val1 in my structure.

    >
    >
    >>The size of size_t is
    >>32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >>machines.

    >
    >
    > I'm not convinced this generalization is valid for all 32-bit or
    > 64-bit machines.
    >

    size_t has to be able to hold the largest size value, so it has to be 64
    bit on a 64 bit system.
    >
    >>I am passing address of this variable to a different function (where it
    >>
    >>accepts only pointer to unsigned int) unsigned int *.

    >
    >
    > This is your problem. Fix it. There are several approaches:
    >
    > (1) Fix the function to accept a pointer to size_t.
    > (2) Copy the size_t into an unsigned int (by assignment), and pass a
    > pointer to *THAT*. If the function might change the value pointed
    > at, copy it back afterwards. However, you're going to have trouble
    > if the value won't FIT in an unsigned int, which itself presents problems.
    > (3) Change the type of the member to unsigned int.
    >

    Agreed, 1 is the preferred solution.

    --
    Ian Collins.
     
    Ian Collins, May 12, 2006
    #10
  11. Guest

    >This is your problem. Fix it. There are several approaches:

    >(1) Fix the function to accept a pointer to size_t.


    I may not be able to do because the function is supplied by a
    library.

    >(2) Copy the size_t into an unsigned int (by assignment), and pass a
    > pointer to *THAT*. If the function might change the value pointed


    > at, copy it back afterwards. However, you're going to have trouble


    > if the value won't FIT in an unsigned int, which itself presents

    problems.

    This is possible. The value will always fit in unsigned int.

    >(3) Change the type of the member to unsigned int.


    This is also not possible as the data type definition is provided by
    some other library.
     
    , May 12, 2006
    #11
  12. Flash Gordon Guest

    Ian Collins wrote:
    > Gordon Burditt wrote:
    >>> I have problem with the code only with 64 bit big endian machine.
    >>> i have a member size_t val1 in my structure.

    >>
    >>> The size of size_t is
    >>> 32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >>> machines.

    >>
    >> I'm not convinced this generalization is valid for all 32-bit or
    >> 64-bit machines.
    >>

    > size_t has to be able to hold the largest size value, so it has to be 64
    > bit on a 64 bit system.


    Just because the system is 64 bit does not mean the compiler has to
    allow you to create a single object with a size that won't fit in a 32
    bit size_t. If it doesn't allow you to create such a large object, why
    make size_t 64 bits?

    >>> I am passing address of this variable to a different function (where it
    >>>
    >>> accepts only pointer to unsigned int) unsigned int *.

    >>
    >> This is your problem. Fix it. There are several approaches:
    >>
    >> (1) Fix the function to accept a pointer to size_t.
    >> (2) Copy the size_t into an unsigned int (by assignment), and pass a
    >> pointer to *THAT*. If the function might change the value pointed
    >> at, copy it back afterwards. However, you're going to have trouble
    >> if the value won't FIT in an unsigned int, which itself presents problems.
    >> (3) Change the type of the member to unsigned int.
    >>

    > Agreed, 1 is the preferred solution.


    Agreed.
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc

    Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
     
    Flash Gordon, May 12, 2006
    #12
  13. CBFalconer Guest

    wrote:
    >
    > Sorry I did't notice the first part of the previous message. I
    > should have provided the context in the first place.


    You are obviously unaware of the problems with the foul google
    interface to usenet. Read the following sig, and the URLs
    referenced in it. Do so before posting again.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, May 12, 2006
    #13
  14. >>>I have problem with the code only with 64 bit big endian machine.
    >>>i have a member size_t val1 in my structure.

    >>
    >>
    >>>The size of size_t is
    >>>32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >>>machines.

    >>
    >>
    >> I'm not convinced this generalization is valid for all 32-bit or
    >> 64-bit machines.
    >>

    >size_t has to be able to hold the largest size value, so it has to be 64
    >bit on a 64 bit system.


    No, it doesn't. It could be 10240 bits, or a whole bunch of values
    all >= 64 bits.

    There is also the possibility that this is a smegmented architecture,
    with the maximum size of a smegment (and therefore an object) being
    2**32. This is the case for the Intel x86 large-code (32 bits),
    small-data (16 bits) model where size_t is 16 bits.


    How is a N-bit system defined again? I thought a system was N-bit
    if an int had N bits. In that case, this 64-bit machine with a
    64-bit unsigned long and a 32-bit unsigned int ISN'T a 64-bit machine.

    Other possible definitions include:
    - The width of a code pointer.
    - The width of a data pointer.
    (Note: the above two can be different. See "medium" and "compact" models
    on an Intel [2345]86. Note that a Pentium can be considered a 48-bit
    machine by this definition.)
    - The value given in marketing literature (in which case it's
    meaningless).
    - The width of the memory data bus (in which case machines like the
    8088 and 8086 have different bittedness but virtually identical
    software architecture.)

    Gordon L. Burditt
     
    Gordon Burditt, May 12, 2006
    #14
  15. Ian Collins Guest

    Flash Gordon wrote:
    > Ian Collins wrote:
    >
    >> Gordon Burditt wrote:
    >>
    >>>> I have problem with the code only with 64 bit big endian machine.
    >>>> i have a member size_t val1 in my structure.
    >>>
    >>>
    >>>> The size of size_t is
    >>>> 32(unsigned int) in 32 bit machines and 64(unsigned long) in 64 bit
    >>>> machines.
    >>>
    >>>
    >>> I'm not convinced this generalization is valid for all 32-bit or
    >>> 64-bit machines.
    >>>

    >> size_t has to be able to hold the largest size value, so it has to be 64
    >> bit on a 64 bit system.

    >
    >
    > Just because the system is 64 bit does not mean the compiler has to
    > allow you to create a single object with a size that won't fit in a 32
    > bit size_t. If it doesn't allow you to create such a large object, why
    > make size_t 64 bits?
    >

    Are you aware of such a system?

    --
    Ian Collins.
     
    Ian Collins, May 12, 2006
    #15
  16. Flash Gordon Guest

    Gordon Burditt wrote:

    <snip>

    > (Note: the above two can be different. See "medium" and "compact" models
    > on an Intel [2345]86. Note that a Pentium can be considered a 48-bit
    > machine by this definition.)
    > - The value given in marketing literature (in which case it's
    > meaningless).
    > - The width of the memory data bus (in which case machines like the
    > 8088 and 8086 have different bittedness but virtually identical
    > software architecture.)


    You should have picked the 80386SX and 30386DX (IIRC) where the SX had a
    16 bit data bus (so it could more easily be used in circuits designed
    for a 286) and the DX had a 32 bit data bus but they had *identical*
    instruction sets. :)
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
     
    Flash Gordon, May 12, 2006
    #16
  17. >> Just because the system is 64 bit does not mean the compiler has to
    >> allow you to create a single object with a size that won't fit in a 32
    >> bit size_t. If it doesn't allow you to create such a large object, why
    >> make size_t 64 bits?
    >>

    >Are you aware of such a system?


    Well, there's one that's close: Intel Pentium in 32-bit mode.
    (People seem to mean that an N-bit system has N *address* bits. In
    the original posting, if bittedness is determined by the size of
    int, a 64-bit system with a 32-bit unsigned int *ISN'T* 64 bits).
    The pointers are 48 bits, but they are segmented, and the largest
    segment is 4G.

    Going down in size a bit, consider Intel Pentium in 16-bit mode
    large model. The largest object is 64k, although pointers are
    32-bits. size_t is 16 bits. You *can* do funky things with pointer
    arithmetic to carry into the segment, but that's called "huge model".

    Gordon L. Burditt
     
    Gordon Burditt, May 12, 2006
    #17
  18. Ian Collins Guest

    Gordon Burditt wrote:
    >>>Just because the system is 64 bit does not mean the compiler has to
    >>>allow you to create a single object with a size that won't fit in a 32
    >>>bit size_t. If it doesn't allow you to create such a large object, why
    >>>make size_t 64 bits?
    >>>

    >>
    >>Are you aware of such a system?

    >
    >
    > Well, there's one that's close: Intel Pentium in 32-bit mode.
    > (People seem to mean that an N-bit system has N *address* bits. In
    > the original posting, if bittedness is determined by the size of
    > int, a 64-bit system with a 32-bit unsigned int *ISN'T* 64 bits).
    > The pointers are 48 bits, but they are segmented, and the largest
    > segment is 4G.
    >
    > Going down in size a bit, consider Intel Pentium in 16-bit mode
    > large model. The largest object is 64k, although pointers are
    > 32-bits. size_t is 16 bits. You *can* do funky things with pointer
    > arithmetic to carry into the segment, but that's called "huge model".
    >

    I've spent many a happy hour tinkering with Intel's segmented
    architecture, but I'm not aware of any current 64 bit system that would
    use a 32 bit size_t.

    --
    Ian Collins.
     
    Ian Collins, May 12, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    1,865
    Timothy Bendfelt
    Jan 19, 2007
  2. gamehack

    Bit shifts and endianness

    gamehack, Jan 5, 2006, in forum: C Programming
    Replies:
    72
    Views:
    6,998
    Dave Thompson
    Jan 11, 2006
  3. endianness and 64-bit machines

    , May 17, 2006, in forum: C Programming
    Replies:
    7
    Views:
    498
    Richard Heathfield
    May 20, 2006
  4. Replies:
    9
    Views:
    1,062
    Juha Nieminen
    Aug 22, 2007
  5. Jeff.M
    Replies:
    6
    Views:
    207
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page