Unaligned pointers question

Discussion in 'C Programming' started by Steven Jones, Oct 22, 2005.

  1. Steven Jones

    Steven Jones Guest

    Up until now, I was under the impression that when one talks about data
    alignment, what one means is at what address some data is stored. For
    instance, if we write

    unsigned int x ;

    assuming that sizeof(unsigned int) is 4 then &x will evaluate to some
    address the value of which will be a multiple of 4. The reasoning is
    analogous for the other fundamental data types supported by a given
    compiler.

    However, I recently came across the following:

    unsigned short * p = (unsigned short *) str ;

    where str has been defined as unsigned char * elsewhere, and points to
    some data. str can point to an address with an arbitrary value, as far as
    divisibility is concerned.

    unsigned short x ;
    unsigned short * y = &x ;

    *y = p[0] ;

    In my naivete, I thought that this last line would result in an unaligned
    access whenever the address p is not a multiple of 2 (assuming that
    sizeof(unsigned short) is 2) but my little test code shows that sometimes
    it does, sometimes it doesn't.

    Can anybody enlighten me here? What is the foolproof criterion to
    determine is some data is correctly aligned?
     
    Steven Jones, Oct 22, 2005
    #1
    1. Advertising

  2. Steven Jones

    Nils Weller Guest

    On 2005-10-22, Steven Jones <> wrote:
    > [...]
    > However, I recently came across the following:
    >
    > unsigned short * p = (unsigned short *) str ;
    >
    > where str has been defined as unsigned char * elsewhere, and points to
    > some data. str can point to an address with an arbitrary value, as far as
    > divisibility is concerned.
    >
    > unsigned short x ;
    > unsigned short * y = &x ;
    >
    > *y = p[0] ;
    >
    > In my naivete, I thought that this last line would result in an unaligned
    > access whenever the address p is not a multiple of 2 (assuming that
    > sizeof(unsigned short) is 2) but my little test code shows that sometimes
    > it does, sometimes it doesn't.


    I have to ask HOW you determined whether that line resulted in an
    unaligned access or not. Your assertion that the divisibility of an
    address indicates the alignment is correct in practice (though the C
    standards do not guarantee that such a relationship between pointers and
    integers exists.)

    However, since unaligned access invokes undefined behavior in C, the
    implementation is free to behave in any way it chooses upon encountering
    such a construct, and that may be may be what you're seeing: Some
    processors require correct alignment for all types and yield a bus error
    for unaligned access, others do not (in particular, the x86 architecture
    can perform misaligned data access in exchange for a performance
    penalty), and still others may perform the access but silently yield
    unwanted results. Some operating systems work around such processor
    limitations by catching alignment faults and building your desired
    results from combining two aligned reads/writes, and some compilers can
    do the same thing in advance, such that the processor never gets to see
    the bad access.

    The fact that the access worked for you does not necessarily mean that
    the address is really correctly aligned.
     
    Nils Weller, Oct 22, 2005
    #2
    1. Advertising

  3. Steven Jones

    Nils Weller Guest

    I hate following up to myself, but somebody's gotta do it ...

    On 2005-10-22, Nils Weller <> wrote:
    > results from combining two aligned reads/writes, and some compilers can
    > do the same thing in advance, such that the processor never gets to see
    > the bad access.


    Actually compilers that try to prevent unaligned reads/writes in advance
    tend to do so by reading/writing the data byte-wise rather than in units
    of the particular type.

    --
    Nils R. Weller, Bremen (Germany)
    My real email address is ``nils<at>gnulinux<dot>nl''
    .... but I'm not speaking for the Software Libre Foundation!
     
    Nils Weller, Oct 22, 2005
    #3
  4. Steven Jones

    Steven Jones Guest

    On Sat, 22 Oct 2005 21:31:44 +0000, Nils Weller wrote:

    > On 2005-10-22, Steven Jones <> wrote:
    >> [...]
    >> However, I recently came across the following:
    >>
    >> unsigned short * p = (unsigned short *) str ;
    >>
    >> where str has been defined as unsigned char * elsewhere, and points to
    >> some data. str can point to an address with an arbitrary value, as far
    >> as divisibility is concerned.
    >>
    >> unsigned short x ;
    >> unsigned short * y = &x ;
    >>
    >> *y = p[0] ;
    >>
    >> In my naivete, I thought that this last line would result in an
    >> unaligned access whenever the address p is not a multiple of 2 (assuming
    >> that sizeof(unsigned short) is 2) but my little test code shows that
    >> sometimes it does, sometimes it doesn't.

    >
    > I have to ask HOW you determined whether that line resulted in an
    > unaligned access or not.


    Well, when I run run the code a big fat warning is printed out that says
    so. This is under Linux x86.

    > Your assertion that the divisibility of an address indicates the
    > alignment is correct in practice (though the C standards do not
    > guarantee that such a relationship between pointers and integers
    > exists.)


    > However, since unaligned access invokes undefined behavior in C, the
    > implementation is free to behave in any way it chooses upon encountering
    > such a construct, and that may be may be what you're seeing: Some
    > processors require correct alignment for all types and yield a bus error
    > for unaligned access, others do not (in particular, the x86 architecture
    > can perform misaligned data access in exchange for a performance
    > penalty), and still others may perform the access but silently yield
    > unwanted results. Some operating systems work around such processor
    > limitations by catching alignment faults and building your desired
    > results from combining two aligned reads/writes, and some compilers can
    > do the same thing in advance, such that the processor never gets to see
    > the bad access.
    >
    > The fact that the access worked for you does not necessarily mean that
    > the address is really correctly aligned.


    Well, this is a nice explanation, but it does not really address the
    issue I raised: Is the divisibility criterion I mentioned the right one
    for determining data alignment, or does this vary so dramatically from
    processor to processor that such criterion is not generally valid?

    I am aware that this is not directly related to the C standard, but it is
    a question that surely arises whenever one writes C code on any platform,
    right?
     
    Steven Jones, Oct 23, 2005
    #4
  5. Steven Jones

    Nils Weller Guest

    On 2005-10-23, Steven Jones <> wrote:
    > On Sat, 22 Oct 2005 21:31:44 +0000, Nils Weller wrote:
    >
    >> On 2005-10-22, Steven Jones <> wrote:
    >>> [...]

    >> I have to ask HOW you determined whether that line resulted in an
    >> unaligned access or not.

    >
    > Well, when I run run the code a big fat warning is printed out that says
    > so. This is under Linux x86.


    Interesting, so you're running a Linux with x86 alignment exceptions
    turned on. The x86 architecture, as I mentioned in my previous message,
    can correctly handle unaligned memory access. However, it is also
    capable of causing an exception upon encountering such an access, just
    like those architectures that always respond with bus errors to
    unaligned access. There's a bit in an x86 control register that can be
    set to select the desired behavior. Most x86 systems do not make use of
    this feature, so misaligned memory access will work on them without any
    indication of a problem except for the increased access time.

    >> Your assertion that the divisibility of an address indicates the
    >> alignment is correct in practice (though the C standards do not
    >> guarantee that such a relationship between pointers and integers
    >> exists.)

    > [...]
    >
    > Well, this is a nice explanation, but it does not really address the
    > issue I raised: Is the divisibility criterion I mentioned the right one
    > for determining data alignment, or does this vary so dramatically from
    > processor to processor that such criterion is not generally valid?


    The very first paragraph of the explanation addresses the issue you
    raised: Yes, the divisibility criterion you mentioned is the right one
    for determining data alignment, in the real world (again, the C standard
    does not say this.)

    --
    Nils R. Weller, Bremen (Germany)
    My real email address is ``nils<at>gnulinux<dot>nl''
    .... but I'm not speaking for the Software Libre Foundation!
     
    Nils Weller, Oct 23, 2005
    #5
  6. Steven Jones

    Steven Jones Guest

    On Sun, 23 Oct 2005 02:04:24 +0000, Nils Weller wrote:

    > The very first paragraph of the explanation addresses the issue you
    > raised: Yes, the divisibility criterion you mentioned is the right one for
    > determining data alignment, in the real world (again, the C standard does
    > not say this.)


    All right. I guess that the way to understand what I am observing is,
    for some cases in which unaligned data access is taking place, the
    platform that I am using is not reacting in any immediately visible way,
    whereas in some others (for whatever reason) it does.
     
    Steven Jones, Oct 23, 2005
    #6
  7. Steven Jones

    Malcolm Guest

    "Steven Jones" <> wrote
    >
    > All right. I guess that the way to understand what I am observing is,
    > for some cases in which unaligned data access is taking place, the
    > platform that I am using is not reacting in any immediately visible way,
    > whereas in some others (for whatever reason) it does.
    >

    Not all processors require data to be aligned.
    Others slow down when they hit unaligned data, but give correct output.
    Others require strict alignment.

    Therefore casting a char * to an unsigned short is asking for trouble.
    Normally there should be no reason to do this, but sometimes you do need to
    play games with memory, in which case flag it as a portability hazard.
     
    Malcolm, Oct 23, 2005
    #7
  8. Steven Jones

    Jack Klein Guest

    On Sun, 23 Oct 2005 01:22:33 GMT, Steven Jones <>
    wrote in comp.lang.c:

    > On Sat, 22 Oct 2005 21:31:44 +0000, Nils Weller wrote:
    >
    > > On 2005-10-22, Steven Jones <> wrote:
    > >> [...]
    > >> However, I recently came across the following:
    > >>
    > >> unsigned short * p = (unsigned short *) str ;
    > >>
    > >> where str has been defined as unsigned char * elsewhere, and points to
    > >> some data. str can point to an address with an arbitrary value, as far
    > >> as divisibility is concerned.
    > >>
    > >> unsigned short x ;
    > >> unsigned short * y = &x ;
    > >>
    > >> *y = p[0] ;
    > >>
    > >> In my naivete, I thought that this last line would result in an
    > >> unaligned access whenever the address p is not a multiple of 2 (assuming
    > >> that sizeof(unsigned short) is 2) but my little test code shows that
    > >> sometimes it does, sometimes it doesn't.

    > >
    > > I have to ask HOW you determined whether that line resulted in an
    > > unaligned access or not.

    >
    > Well, when I run run the code a big fat warning is printed out that says
    > so. This is under Linux x86.
    >
    > > Your assertion that the divisibility of an address indicates the
    > > alignment is correct in practice (though the C standards do not
    > > guarantee that such a relationship between pointers and integers
    > > exists.)

    >
    > > However, since unaligned access invokes undefined behavior in C, the
    > > implementation is free to behave in any way it chooses upon encountering
    > > such a construct, and that may be may be what you're seeing: Some
    > > processors require correct alignment for all types and yield a bus error
    > > for unaligned access, others do not (in particular, the x86 architecture
    > > can perform misaligned data access in exchange for a performance
    > > penalty), and still others may perform the access but silently yield
    > > unwanted results. Some operating systems work around such processor
    > > limitations by catching alignment faults and building your desired
    > > results from combining two aligned reads/writes, and some compilers can
    > > do the same thing in advance, such that the processor never gets to see
    > > the bad access.
    > >
    > > The fact that the access worked for you does not necessarily mean that
    > > the address is really correctly aligned.

    >
    > Well, this is a nice explanation, but it does not really address the
    > issue I raised: Is the divisibility criterion I mentioned the right one
    > for determining data alignment, or does this vary so dramatically from
    > processor to processor that such criterion is not generally valid?
    >
    > I am aware that this is not directly related to the C standard, but it is
    > a question that surely arises whenever one writes C code on any platform,
    > right?


    No, I would say that you are wrong. There is never any need to write
    C code that accesses an lvalue via a pointer with incorrect alignment.

    Most such code is written by those who decide, generally without
    evidence or testing, that doing things properly is "too slow".

    Almost all such decisions are based on incorrect assumptions
    (premature optimization and all that) that would turn out to be just
    plain wrong if actually measured or tested.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Oct 23, 2005
    #8
    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. Pavel A.

    Does UNALIGNED attribute exist in GNU C?

    Pavel A., May 19, 2005, in forum: C Programming
    Replies:
    18
    Views:
    1,131
    Thomas Carter
    Jun 20, 2005
  2. Replies:
    7
    Views:
    421
    Walter Roberson
    Nov 8, 2005
  3. Steven Woody

    using member address of an unaligned structure

    Steven Woody, Feb 8, 2006, in forum: C Programming
    Replies:
    5
    Views:
    811
    Keith Thompson
    Feb 8, 2006
  4. aleksa

    Unaligned access

    aleksa, May 5, 2010, in forum: C Programming
    Replies:
    15
    Views:
    665
    bart.c
    May 5, 2010
  5. James Harris

    Struct with unaligned fields

    James Harris, Aug 22, 2013, in forum: C Programming
    Replies:
    58
    Views:
    694
    David Thompson
    Sep 4, 2013
Loading...

Share This Page