Dealing with an -Wincompatible-pointer-types warning

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the following code which is causing the -Wincompatible-pointer-types warning:

 

union SensorData
{
    uint64_t raw_sensor_data;
    struct
    {
        uint16_t humidity_data;
        uint16_t temperature_data;
    };
} sensor_data;

/* ... Bunch of other code ...*/

uint8_t *raw_sensor_data_bytes = &sensor_data.raw_sensor_data;
uint8_t checksum = raw_sensor_data_bytes[0];
uint8_t sum = 0;
for (uint8_t i = 1; i < 8; i++)
{
    sum += raw_sensor_data_bytes[i];
}

The error gets called for the line

uint8_t *raw_sensor_data_bytes = &sensor_data.raw_sensor_data;

I  understand why the error is getting called: it's getting called because I have a pointer that expects to be pointing to an 8 bit integer, when in reality it is pointing to a 64-bit integer; however, this is for (what I currently think) a good reason. I need to split that 64-bit integer into 8-bit segments, so I thought that it would be fine to create a pointer that would, in effect, divide the 64-bit integer into 8 8-bit segments; however, doing this is causing the aformentioned warning. Is there a more proper way to do what I am trying to do that would get rid of the warning, or is it possible for me to just simply override the warning in some way, or do I just have to ignore it?

This topic has a solution.
Last Edited: Sat. May 7, 2022 - 08:56 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Type cast the address to uint8_t *

 

uint8_t *raw_sensor_data_bytes = (uint8_t *)&sensor_data.raw_sensor_data;

 

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Couldn't you add a rawbytes array to the union and avoid all the wrangling outside?

Also, the two uint16s only cover half the uint64. That's OK in your app?

uint8_t rawbytes[8];

 

Mike

When you're used to privilege, equality feels like oppression. / Malena Ernman

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

An example I posted in one of your other threads-

 

https://godbolt.org/z/dYbo7v7GE

 

You make that union member an array since that is one of the ways you want to access the data. No casting needed.

 

Casting should be avoided if possible. Can't really avoid it many times, but its a good idea to rethink if there is another way so there is no longer a need to cast. In this case a rethink about what you actually wanted (an array of bytes, not a uint64_t) solves the problem and eliminates an unnecessary casting. The biggest problem with casting is your code takes a hit on readability and ability to understand what is happening. Not an evil thing, just something to avoid if possible.

Last Edited: Sun. May 8, 2022 - 06:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Izerpizer wrote:
however, doing this is causing the aformentioned warning.

 

This "warning" is actually an "error" (a constraint violation) reported as "warning" just because your C compiler is configured to report such errors as "warnings".

 

C is a statically typed language. It does not allow implicit conversions between unrelated pointer types.

 

Izerpizer wrote:
so I thought that it would be fine to create a pointer that would, in effect, divide the 64-bit integer into 8 8-bit segments

 

It is not as "fine" as you might think, since the result is implementation-defined. But if you really want to do this you have to request the conversion explicitly.

Dessine-moi un mouton

Last Edited: Sun. May 8, 2022 - 04:06 PM