3

I am not able to find out how to remove the above warning from the below line of code. data is is void pointer and as part of callback function will be receiving string in the data pointer. As I have typecast the void pointer but compiler still showing the warning.

There are basically two warnings showing up on the below line. 1. dereferencing 'void *' pointer 2. taking address of expression of type 'void

 service_ind = atoi((const char*)&data[at_response.param[0].start_of_value_index]) ? TRUE:FALSE ;

Below are required information

void * data;
AT_PARSER_RESPONSE at_response;

typedef struct
{

/*Other parameters */

AT_PARAM  param[AT_MAX_NUM_PARAM];

}AT_PARSER_RESPONSE
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Abhi
  • 189
  • 1
  • 8
  • 1
    Please show the definitions of `data`, `at_response`, and whatever the type of `at_response.param[0]` is. – aschepler Jun 02 '17 at 12:24
  • I'm thinking (still my first cup of coffee) the order of precedence is not what you think for `(const char*)&data[at_response.param[0].start_of_value_index]` (i.e. you may need extra parenthesis), or that you need to cast `data` to a valid type before using `[]`, depending on what `data` *really* is. – crashmstr Jun 02 '17 at 12:33

1 Answers1

7

Quoting C11, chapter §6.5.3.2:

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

So, your code causes undefined behavior.

Also, related, from chapter §6.2.5:

The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

So, a pointer to void is an invalid operand for dereference.


One probable practical case and the possible solution

Sometimes, for making generics, we cast a certain pointer to void *, pass that as argument to a function and then, inside a function we cast it back to the original type, based on some known information. This is, as per chapter §6.3.2.3, perfectly valid:

[...] A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

If this is your case, and you're dereferencing inside the function, you can cast the pointer to either

before dereferencing.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • can you please add the link you are quoting from? – CIsForCookies Jun 02 '17 at 12:28
  • 1
    @CIsForCookies as I mentioned, it's from C11 standard, the actuals are sold but you can get some draft version online which are pretty accurate. :) – Sourav Ghosh Jun 02 '17 at 12:30
  • 1
    *You can however, cast the pointer to a valid type, before dereferencing.* Which also can be undefined behavior as it can [violate strict aliasing](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) if, for example, you start with a `char *`, assign it to a `void *`, then cast it to a `double *` and try to dereference it. – Andrew Henle Jun 02 '17 at 12:31
  • @AndrewHenle makes much sense, let me amend my answer to remove that pitfall, thanks sir!! – Sourav Ghosh Jun 02 '17 at 12:32
  • 1
    @CIsForCookies-- [here](http://port70.net/~nsz/c/c11/n1570.html#6.5.3.2p4) and [here](http://port70.net/~nsz/c/c11/n1570.html#6.2.5p19). – ad absurdum Jun 02 '17 at 12:34
  • @AndrewHenle that UB can be caused from every standard casting between a small data type and a bigger one, wouldn't it? – CIsForCookies Jun 02 '17 at 12:35
  • @DavidBowling any better? – Sourav Ghosh Jun 02 '17 at 12:37
  • 1
    I think you mean @AndrewHenle-- I was just providing a couple of links for CisForCookies – ad absurdum Jun 02 '17 at 12:40
  • 1
    @CIsForCookies The other way, too, with the exception of casts to `[unsigned] char *`. Per [the standard](http://www.open-std.org/Jtc1/sc22/wg14/www/docs/n1570.pdf): *A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object.* – Andrew Henle Jun 02 '17 at 12:42