Thread: GCC Warnings pointers

  1. #1
    Registered User
    Join Date
    Mar 2018
    Posts
    7

    GCC Warnings pointers

    Code:
    void jcp_parse_and_reply(char *data, int len, char *ipaddr)
    {
            struct jcp_header *jcpheader = (struct jcp_header*)data;
            struct dev_state *ds         = (char*)data+sizeof(struct jcp_header);

    I'm trying to write the entire project with -Wall on in GCC.

    The definition of 'ds' works fine, but GCC warns "initialization from incompatible pointer type".

    How do I do the same job in way free from warnings from GCC ?

    Thanks,
    Jon

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    So use a different cast.
    struct dev_state *ds = (struct dev_state *)(data+sizeof(struct jcp_header));
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2018
    Posts
    7
    Great job, thanks

    I originally started with this:

    struct dev_state *ds = (struct dev_state *)data+sizeof(struct jcp_header);

    Compiled ok, but did not work? The extra brackets are needed, not sure I understand why...

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Compiled ok, but did not work? The extra brackets are needed, not sure I understand why...
    Because pointer arithmetic.

    > struct dev_state *ds = (struct dev_state *)(data+sizeof(struct jcp_header));
    data is a char pointer, so the addition advances by so many bytes.

    > struct dev_state *ds = (struct dev_state *)data+sizeof(struct jcp_header);
    You made data a struct dev_state pointer, so the addition effectively indexes the byte at sizeof(struct jcp_header) * sizeof(struct dev_state)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2018
    Posts
    7
    This is just my mental block, I've made this same mistake before. data is char* so I always expect (wrongly) data+offset to behave at pointer + offset bytes. I will try and learn ! Thanks again.

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Or try this:

    Code:
            struct dev_state *ds         = (struct dev_state *)&jcpheader[1];

  7. #7
    Registered User
    Join Date
    May 2019
    Posts
    214
    @jonshouse, a quick 'tutorial' about this.

    As @salem points out, this is about pointer arithmetic.

    I thought it may be useful to see how that works in two primary forms.

    First, to be clear at the risk of being pedantic, the raw block of memory passed the the function via data * is, at that point, declared to be char *'s, which are typically (99.9999999% of the time in modern code) 1 byte in size.

    The format (presumably from your code, and likely a fact) is such that a struct jcp_header is first in this raw memory block, and it is followed by a struct dev_state.

    The code posted here:

    Code:
    struct dev_state *ds = (struct dev_state *)(data+sizeof(struct jcp_header));
    Works and is correct when data is a raw block of memory measured in bytes.

    The type is what establishes that measurement. In this case, data is of type char *, where each char is 1 byte in length.

    One of the primary purposes of pointer arithmetic is to advance through arrays. If a pointer is of type integer, and if integers are 4 bytes long, this would sequence through an integer array:

    Code:
    for( int * p = arrbase; p < limit; ++p ) { *p = 0; }
    This naive code assumes arrbase in an int * to an array, and limit is an int * set to the end of the array. Every increment of p in this case moves the pointer forward by 4 bytes, because it is an integer type and integers are 4 bytes in this case.

    If the compiler is configured for a different CPU where integers are 8 bytes, then p would be advanced 8 bytes for every increment for the same reason.

    It is true, also, if p were a struct of some kind, such that an increment of p would advance the pointer by whatever the size of that struct is.

    This brings me to this point:

    Code:
    struct jcp_header *jcp_ptr = ( struct jcp_header * ) data;
    
    struct dev_state *devptr = (struct dev_state *) ( jcp_ptr +1 );
    The parenthesis are important here. The second line is effectively the same as:

    Code:
    struct dev_state *ds         = (struct dev_state *)&jcpheader[1];
    Both forms treat jcpheader (or jcp_header *) as an array, and calculate the position of the next entry in that array, but then cast that to a dev_state *.

    This is also the same thing as

    Code:
    struct dev_state *devptr = (struct dev_state *)( data + sizeof( struct jcp_header ) );
    In this last case, however, data is a char *, so addition is based on the size of a char, making it work like standard addition.

    In this example:

    Code:
    struct dev_state *devptr = (struct dev_state *) ( jcp_ptr + 1 );
    The addition of 1 to jcp_ptr is based on the size of a jcp_header type, the sizeof( struct jcp_header).

    If that were "jcp_ptr + 2", the pointer would have moved the size of 2 jcp_headers, and if it were "jcp_ptr + 3", it would have moved the size of 3 jcp_headers.

    This is the same as jcp_ptr[1], jcp_ptr[2] or jcp_ptr[3].

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. for/while Warnings
    By reaperman in forum C++ Programming
    Replies: 3
    Last Post: 10-28-2008, 04:14 PM
  2. How DO I Get Rid Of Warnings?
    By bumfluff in forum Windows Programming
    Replies: 3
    Last Post: 11-24-2006, 06:34 PM
  3. GCC Warnings
    By 00Sven in forum C Programming
    Replies: 12
    Last Post: 05-03-2006, 04:40 AM
  4. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  5. what do these warnings mean
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 02-08-2002, 04:23 PM

Tags for this Thread