64 bit design

Discussion in 'C Programming' started by Balban, Oct 15, 2010.

  1. Balban

    Balban Guest

    Hello,

    I wrote some piece of software that mostly assumes 32 bit systems. I
    defined types such as u32, u64. The general convention I use has been
    always to use int or unsigned int, and when I use a pointer for
    arithmetic I use unsigned long (I never target 16 bit and this is
    mostly safe on 32bit/64bit systems), and I use u32, u64 only when I am
    sure that the type has to be that size.

    Now, If I move to a 64 bit system, what precautions should I consider
    to support my software?

    One issue is the API that I provide. Consider this function prototype:

    int my_api_call(unsigned int type, unsigned int flags);

    There are API functions like this and most of them take flags in an
    unsigned int. If I passed arguments in u64 today, it would mean
    passing too much data in 32 bit sysems. If I continue to pass unsigned
    int, the flags provided in 0-31 would be fine on both systems, but I
    won't be able to pass anything on 32 onwards in a 32 bit system. Is
    there good way to design this right from the start?

    Thanks,

    Bahadir
    Balban, Oct 15, 2010
    #1
    1. Advertising

  2. Balban wrote:

    > I wrote some piece of software that mostly assumes 32 bit systems. I
    > defined types such as u32, u64. The general convention I use has been
    > always to use int or unsigned int, and when I use a pointer for
    > arithmetic I use unsigned long (I never target 16 bit and this is
    > mostly safe on 32bit/64bit systems), and I use u32, u64 only when I am
    > sure that the type has to be that size.
    >
    > Now, If I move to a 64 bit system, what precautions should I consider
    > to support my software?


    Using "unsigned long" for pointer arithmetic may lead to unpleasant
    results on 64-bit systems, depending on the data model (LLP64, LP64,
    SILP64) they implement. To be safe, you should rather use variables
    of type size_t/unintptr_t and ptrdiff_t/intptr_t for array indexing
    and pointer arithmetic. For example, "unsigned long" will work on
    both 32- and 64-bit Linux and Unix systems, but fail (silently!) on
    64-bit Windows. You may find this paper <http://linkpin.de/sbkuqf>
    helpful, as it discusses this topic in depth.

    > One issue is the API that I provide. Consider this function prototype:
    >
    > int my_api_call(unsigned int type, unsigned int flags);
    >
    > There are API functions like this and most of them take flags in an
    > unsigned int. If I passed arguments in u64 today, it would mean
    > passing too much data in 32 bit sysems. If I continue to pass unsigned
    > int, the flags provided in 0-31 would be fine on both systems, but I
    > won't be able to pass anything on 32 onwards in a 32 bit system. Is
    > there good way to design this right from the start?


    Merely using a 32-bit system doesn't also mean that the type "int" will
    use 32 bits: a C compiler for that system may well choose to implement
    16-bit integers. The C standard defines various types (in <stdint.h>)
    such as "uint32_t" that should be used to write portable code.


    Cheers,
    mike
    Michael Schumacher, Oct 15, 2010
    #2
    1. Advertising

  3. Balban <> writes:
    > I wrote some piece of software that mostly assumes 32 bit systems. I
    > defined types such as u32, u64. The general convention I use has been
    > always to use int or unsigned int, and when I use a pointer for
    > arithmetic I use unsigned long (I never target 16 bit and this is
    > mostly safe on 32bit/64bit systems), and I use u32, u64 only when I am
    > sure that the type has to be that size.

    [...]

    What exactly do you mean by "when I use a pointer for arithmetic
    I use unsigned long"?

    I've seen code that converts a pointer to an integer performs
    arithmetic on the integer, and then converts back to a pointer.
    If you're doing that, don't. It's non-portable and unnecessary.
    Just perform arithmetic on the pointer value itself.

    If you just mean that you're adding or subtracting unsigned long
    values to pointer values, that's probably ok -- but it might make
    more sense to use size_t.

    Can you show us some examples?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Oct 15, 2010
    #3
    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. kumar
    Replies:
    8
    Views:
    3,511
    Vikram
    Feb 17, 2004
  2. Replies:
    3
    Views:
    1,720
    Timothy Bendfelt
    Jan 19, 2007
  3. Replies:
    9
    Views:
    941
    Juha Nieminen
    Aug 22, 2007
  4. Jeff.M
    Replies:
    6
    Views:
    163
    Lasse Reichstein Nielsen
    May 4, 2009
  5. lokesh kumar
    Replies:
    1
    Views:
    398
Loading...

Share This Page