Memory allignment/type casting question

Discussion in 'C Programming' started by MisterE, Oct 8, 2008.

  1. MisterE

    MisterE Guest

    What happens when you type cast like this:

    (note this is code i just typed cause I dont have a compiler ATM):
    #include <stdlib.h>
    #include <stdio.h>

    int main (int argc, char*argv[])
    {
    unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    unsigned int *i1, *i2, *i3;

    i1 = &c[0];
    i2 = &c[1];
    i3 = &c[2];

    printf("%x %x %x",*i1,*i2,*i3);
    return 0;
    }

    What output will be printed? I have noticed that some some systems require
    integers to be from alligned address etc. others don't. One system has bytes
    in i2 and i3 that are not part of c array at all (ie outputting things like
    0xFF01 0xFE02 0xFF03)

    Is the behavoir defined in anyway at all for anything? Or should the value
    of the whole integer be undefined?

    The reason I ask this is I have to port some craptastic code that has
    pointers of different types randomly pointing to position in an array of
    chars... and as you would expect its behaves differently on every compiler.
    MisterE, Oct 8, 2008
    #1
    1. Advertising

  2. MisterE

    Ian Collins Guest

    MisterE wrote:
    > What happens when you type cast like this:
    >
    > (note this is code i just typed cause I dont have a compiler ATM):
    > #include <stdlib.h>
    > #include <stdio.h>
    >
    > int main (int argc, char*argv[])
    > {
    > unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    > unsigned int *i1, *i2, *i3;
    >
    > i1 = &c[0];
    > i2 = &c[1];
    > i3 = &c[2];
    >

    None of those should compile without a cast.

    > printf("%x %x %x",*i1,*i2,*i3);
    > return 0;
    > }
    >
    > What output will be printed? I have noticed that some some systems require
    > integers to be from alligned address etc. others don't. One system has bytes
    > in i2 and i3 that are not part of c array at all (ie outputting things like
    > 0xFF01 0xFE02 0xFF03)
    >
    > Is the behavoir defined in anyway at all for anything? Or should the value
    > of the whole integer be undefined?
    >

    No, it is totally platform specific.

    > The reason I ask this is I have to port some craptastic code that has
    > pointers of different types randomly pointing to position in an array of
    > chars... and as you would expect its behaves differently on every compiler.
    >

    Good luck, you'll probably need it.

    --
    Ian Collins.
    Ian Collins, Oct 8, 2008
    #2
    1. Advertising

  3. MisterE

    Guest

    #include <stdlib.h>
    #include <stdio.h>

    int main (int argc, char*argv[])
    {
    unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    unsigned int *i1, *i2, *i3;


    i1 = (unsigned int *)&c[0];
    i2 = (unsigned int *)&c[1];
    i3 = (unsigned int *)&c[2];


    printf("0x%06x 0x%06x 0x%06x",i1,i2,i3);

    system("PAUSE");
    return 0;
    }
    , Oct 8, 2008
    #3
  4. MisterE

    Guest

    On Oct 8, 9:41 am, "MisterE" <> wrote:
    <snip>
    > Is the behavoir defined in anyway at all for anything? Or should the value
    > of the whole integer be undefined?


    UB.

    > The reason I ask this is I have to port some craptastic code that has
    > pointers of different types randomly pointing to position in an array of
    > chars... and as you would expect its behaves differently on every compiler.


    Great, then you don't care you invoke undefined behavior, you just
    want it to work under certain compilers.
    Why do you post in comp.lang.c? It'd be more appropriate to ask in
    each and every implementation group about how you'd make such code
    generate the desired output.
    , Oct 8, 2008
    #4
  5. MisterE

    James Kuyper Guest

    MisterE wrote:
    > What happens when you type cast like this:


    Your sample code doesn't have any type casts. It should, but it doesn't.

    > (note this is code i just typed cause I dont have a compiler ATM):
    > #include <stdlib.h>
    > #include <stdio.h>
    >
    > int main (int argc, char*argv[])
    > {
    > unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    > unsigned int *i1, *i2, *i3;
    >
    > i1 = &c[0];
    > i2 = &c[1];
    > i3 = &c[2];


    Those assignments require the type casts that you mentioned, but did not
    provide. Without them there is a constraint violation (6.5.16.1p1).

    If you add (unsigned*) before the '&' in each of those statements,
    you'll get an implementation-defined result whose meaning is not
    specified in any way by the C standard. If the alignment requirement of
    unsigned is any number greater than 1, then the behavior of that
    conversion is undefined for at least one of those statements.

    > printf("%x %x %x",*i1,*i2,*i3);


    Even if the conversions themselves did not cause something awful to
    happen, the standard does not define where the resulting pointer points,
    or even whether it points at any valid location, so the behavior of the
    expressions "*i1", "*i2" and "*i3" would also be undefined for that reason.

    Even if those pointers do point into the array 'c', the behavior is
    still undefined, because you're accessing the memory through an lvalue
    of a type that isn't compatible with the effective type of the object
    stored in that location.

    In practice, for an implementations without alignment restrictions on
    unsigned int, the result should be to interpret the appropriate bytes of
    'c' as if they were unsigned int. However, you should never write code
    that is intended to be even remotely portable, which makes such assumptions.

    > return 0;
    > }
    >
    > What output will be printed? I have noticed that some some systems require
    > integers to be from alligned address etc. others don't. One system has bytes
    > in i2 and i3 that are not part of c array at all (ie outputting things like
    > 0xFF01 0xFE02 0xFF03)


    Since the behavior is undefined, in principle an implementation can
    print just about anything at this point. In practice, I would not have
    expected that result. Perhaps if you identify the compiler, the
    operating system, and the CPU, someone else can give you a better
    explanation for those results than I can.

    > Is the behavoir defined in anyway at all for anything? Or should the value
    > of the whole integer be undefined?


    No. The behavior of your entire program is undefined, not just the value
    of the integer.

    > The reason I ask this is I have to port some craptastic code that has
    > pointers of different types randomly pointing to position in an array of
    > chars... and as you would expect its behaves differently on every compiler.


    Lovely! The positions are probably not as random as they seem; otherwise
    it wouldn't even work on one compiler (I assume that there is at least
    one compiler where it actually works?).
    James Kuyper, Oct 8, 2008
    #5
  6. MisterE

    James Kuyper Guest

    wrote:
    > #include <stdlib.h>
    > #include <stdio.h>
    >
    > int main (int argc, char*argv[])
    > {
    > unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    > unsigned int *i1, *i2, *i3;
    >
    >
    > i1 = (unsigned int *)&c[0];
    > i2 = (unsigned int *)&c[1];
    > i3 = (unsigned int *)&c[2];
    >
    >
    > printf("0x%06x 0x%06x 0x%06x",i1,i2,i3);
    >
    > system("PAUSE");


    That is a gratuitously unportable piece of code. 'PAUSE' might not even
    be supported by system() on the OP's machine; it's not supported on any
    machine I program on. Even if it is supported, it might not do what you
    expect it to do.

    > return 0;
    > }
    James Kuyper, Oct 8, 2008
    #6
  7. MisterE

    CBFalconer Guest

    MisterE wrote:
    >
    > What happens when you type cast like this:
    >
    > (note this is code i just typed cause I dont have a compiler ATM):
    > #include <stdlib.h>
    > #include <stdio.h>
    >
    > int main (int argc, char*argv[]) {
    > unsigned char c[] = {0,1,2,3,4,5,6,7,8,9,10};
    > unsigned int *i1, *i2, *i3;
    >
    > i1 = &c[0];
    > i2 = &c[1];
    > i3 = &c[2];
    >
    > printf("%x %x %x",*i1,*i2,*i3);
    > return 0;
    > }
    >
    > What output will be printed? I have noticed that some some systems
    > require integers to be from alligned address etc. others don't. One
    > system has bytes in i2 and i3 that are not part of c array at all
    > (ie outputting things like 0xFF01 0xFE02 0xFF03)


    If any. Depending on system, the values in i2 and i3 are probably
    illegal int pointers, and anything can happen. The assignments to
    them should have generated compilation errors.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
    CBFalconer, Oct 9, 2008
    #7
    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. Aitham alama

    Center allignment

    Aitham alama, Jul 18, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    334
    John Saunders
    Jul 18, 2004
  2. EB
    Replies:
    7
    Views:
    492
    Dale King
    Feb 16, 2004
  3. James

    allignment

    James, Mar 24, 2006, in forum: HTML
    Replies:
    5
    Views:
    512
    dorayme
    Mar 25, 2006
  4. Anthony

    allignment of structure

    Anthony, Nov 11, 2003, in forum: C++
    Replies:
    1
    Views:
    528
    Victor Bazarov
    Nov 11, 2003
  5. heyo
    Replies:
    3
    Views:
    885
    Dan Pop
    Apr 1, 2004
Loading...

Share This Page