__ptr64 in GCC

Discussion in 'C Programming' started by morbidpriest, Aug 15, 2005.

  1. morbidpriest

    morbidpriest Guest

    Hello folks,

    I need to define 64 bit pointers in C structs that are going to be
    common to 32 bit and 64 bit platforms. I need the layout of all the
    variables in the structure to be 100% consistent between architectures.


    Basically I want a way to pad out the pointer variables so that they
    will always be 64 bit in length, even when compiled in a 32 bit
    environment.

    Microsoft have a solution to this in the form of __ptr64.
    Unfortunately GCC does not seem to have this feature - the closest I
    could find is __attribute__ ((aligned (8))). This seemed like a good
    idea initially but it's not the same thing, given that the variables
    need to be padded out, aligning them does not really give the correct
    result (I tried and failed).

    So does anyone have any suggestions on how to emulate __ptr64 in GCC as
    cleanly as possible, I have been trying and am completely out of ideas
    at this point...
     
    morbidpriest, Aug 15, 2005
    #1
    1. Advertisements

  2. I'm not sure if this is on topic, the platform/implementation defined
    behaviour and features.
    I think you're not talking about far pointers, which in regular 32-bit
    protected mode are 6 bytes long, but I'd expect them to occupy 8 bytes (due
    to alignment done by a compiler that supports them).

    But, the thing is, gcc doesn't support far pointers. And I have doubts about
    supporting 64 bit pointers for 64 bit modes either.
    That would only align, IMO. The best type (if 64 bit pointers aren't
    supported at all) to store 64 bit addresses would be unsigned long long,
    which is supported by gcc.
    You could mimick to some degree 64-bit pointers using a C++ class with
    overloaded operators such as +, -, [], etc.

    Alex
     
    Alexei A. Frounze, Aug 15, 2005
    #2
    1. Advertisements

  3. Are you sure you really need that? If a structure contains pointers,
    you can't meaningfully share it between architectures, or even between
    different runs of the same program on the same machine.

    The most portable way to share data across architectures is to convert
    everything to streams of bytes. The byte stream can be either the
    broken-down values (e.g., the integer 30000 becomes {0x75, 0x30}) or
    text (the integer 30000 becomes the string "30000"). Floating-point
    can be more difficult. There's no good way to represent pointers this
    way, which reflects the fact that pointer values are inherently
    non-portable.

    If not all the systems in question use 8-bit bytes (CHAR_BIT==8),
    things could be more difficult.

    But if you really need to do this (e.g., if you need the other members
    to be laid out consistently and you're not going to try to use the
    pointer values), you can do something like this:

    union ptr64 {
    void *ptr;
    char dummy[8]; /* again, assumes CHAR_BIT==8 */
    }

    But you still have the problem of making sure everything else is
    aligned properly. Compilers can insert padding as they like, and they
    aren't required to document how they do so, and this problem isn't
    limited to pointers.
     
    Keith Thompson, Aug 15, 2005
    #3
  4. morbidpriest

    Ian Guest

    You will have to use alignment, there must be a pragma in gcc for this.
    A 64 bit pointer has no meaning in 32 bit land.

    you could use a union and a (cough) macro to fake it, something like:

    struct X
    {
    #if defined _LP64
    # define Ptr64 { void* ptr; }
    #else
    # define Ptr64 { void* ptr; uint32_t pad; }
    #endif
    struct Ptr64 ptrStruct;

    #define ptr ptrStruct.ptr
    };

    It's not only pointers that will differ, if you have a mix of uint32_t
    and uint64_t members, the structure size will differ as well.

    Ian
     
    Ian, Aug 16, 2005
    #4
  5. morbidpriest

    tedu Guest

    Separate out the data that moves from the data that doesn't. Putting a
    pointer into a struct that is read by another process, let alone
    another platform, doesn't accomplish anything.
     
    tedu, Aug 16, 2005
    #5
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.