Treating 'char' Structure Members as Contiguous Bytes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin

    Treating 'char' Structure Members as Contiguous Bytes

    The following compiles cleanly on gcc3.0.4 using -W -Wall -ansi -
    pedantic. Lint gives this warning:
    _
    p_member_09 = p_start + OFFSET_TO_MEMBE R_09;
    t_offset.c 27 Warning 416: creation of out-of-bounds pointer (33
    beyond end of data) by operator ptr+int' [Reference: file t_offset.c:
    lines 26, 27]

    The underscore Lint uses to indicate the point of warning is over the
    'O' in OFFSET_TO_MEMBE R_09.

    My question is this. Is the technique used here well-defined and safe
    practice?


    typedef unsigned char uchar;

    struct byte_array {
    uchar member_01;
    uchar member_02[8];
    uchar member_03[2];
    uchar member_04[2];
    uchar member_05[8];
    uchar member_06[2];
    uchar member_07[2];
    uchar member_08[8];
    uchar member_09[2];
    uchar member_10[2];
    };

    struct byte_array byte_array;

    #define OFFSET_TO_MEMBE R_06 21
    #define OFFSET_TO_MEMBE R_09 33

    int main( void )
    {
    uchar *p_start;
    uchar *p_member_09;

    p_start = &byte_array.mem ber_01;
    p_member_09 = p_start + OFFSET_TO_MEMBE R_09;

    return 0;
    }
  • Thad Smith

    #2
    Re: Treating 'char' Structure Members as Contiguous Bytes

    Martin wrote:
    The following compiles cleanly on gcc3.0.4 using -W -Wall -ansi -
    pedantic. Lint gives this warning:
    _
    p_member_09 = p_start + OFFSET_TO_MEMBE R_09;
    t_offset.c 27 Warning 416: creation of out-of-bounds pointer (33
    beyond end of data) by operator ptr+int' [Reference: file t_offset.c:
    lines 26, 27]
    >
    The underscore Lint uses to indicate the point of warning is over the
    'O' in OFFSET_TO_MEMBE R_09.
    >
    My question is this. Is the technique used here well-defined and safe
    practice?
    >
    >
    typedef unsigned char uchar;
    >
    struct byte_array {
    uchar member_01;
    uchar member_02[8];
    uchar member_03[2];
    uchar member_04[2];
    uchar member_05[8];
    uchar member_06[2];
    uchar member_07[2];
    uchar member_08[8];
    uchar member_09[2];
    uchar member_10[2];
    };
    >
    struct byte_array byte_array;
    >
    #define OFFSET_TO_MEMBE R_06 21
    #define OFFSET_TO_MEMBE R_09 33
    >
    int main( void )
    {
    uchar *p_start;
    uchar *p_member_09;
    >
    p_start = &byte_array.mem ber_01;
    p_member_09 = p_start + OFFSET_TO_MEMBE R_09;
    >
    return 0;
    }
    It is not defined because the struct may have padding between members
    (although it is unlikely when the members are arrays of unsigned char).

    You can instead write
    p_member_09 = byte_array.memb er_09;
    or
    p_member_09 = (uchar*)byte_ar ray + offsetof (struct byte_array, member_09);


    --
    Thad

    Comment

    • Richard Bos

      #3
      Re: Treating 'char' Structure Members as Contiguous Bytes

      Martin <martin.o_brien @which.netwrote :
      The following compiles cleanly on gcc3.0.4 using -W -Wall -ansi -
      pedantic. Lint gives this warning:
      _
      p_member_09 = p_start + OFFSET_TO_MEMBE R_09;
      t_offset.c 27 Warning 416: creation of out-of-bounds pointer (33
      beyond end of data) by operator ptr+int' [Reference: file t_offset.c:
      lines 26, 27]
      My question is this. Is the technique used here well-defined and safe
      practice?
      I'll let others figure out the exact safety of the technique you use -
      my first instincts say that it's undefined behaviour in theory, but very
      unlikely to break - and suggest that regardless of the outcome, you
      switch to a guaranteed safe technique: use offsetof(). You'll need to
      #include <stddef.h>.

      Richard

      Comment

      • Army1987

        #4
        Re: Treating 'char' Structure Members as Contiguous Bytes

        Martin wrote:
        [...]
        typedef unsigned char uchar;
        >
        struct byte_array {
        uchar member_01;
        uchar member_02[8];
        [...]
        uchar member_10[2];
        };
        >
        struct byte_array byte_array;
        >
        #define OFFSET_TO_MEMBE R_06 21
        #define OFFSET_TO_MEMBE R_09 33
        #include <stddef.h>
        >
        int main( void )
        {
        uchar *p_start;
        uchar *p_member_09;
        >
        p_start = &byte_array.mem ber_01;
        p_member_09 = p_start + OFFSET_TO_MEMBE R_09;
        Why not p_start + offsetof(byte_a rray, member_09)?
        [...]


        --
        Army1987 (Replace "NOSPAM" with "email")

        Comment

        Working...