Commit 2fc589293066d934bfdfbdff320574e1ea2f5c8a
1 parent
170b042c
Implement the register <-> float conversion without breaking aliasing rules.
The previous implementation dereferenced a type-puned pointer, which is illegal according to ANSI C. Some newer versions of GCC will complain about this. This implementation uses "memcpy" to avoid this problem.
Showing
1 changed file
with
9 additions
and
9 deletions
src/modbus.c
| @@ -1988,20 +1988,20 @@ uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits) | @@ -1988,20 +1988,20 @@ uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits) | ||
| 1988 | /* Read a float from 4 bytes in Modbus format */ | 1988 | /* Read a float from 4 bytes in Modbus format */ |
| 1989 | float modbus_read_float(const uint16_t *src) | 1989 | float modbus_read_float(const uint16_t *src) |
| 1990 | { | 1990 | { |
| 1991 | - float real; | ||
| 1992 | - uint32_t ireal = (src[1] << 16) + src[0]; | ||
| 1993 | - real = *((float *)&ireal); | 1991 | + float r = 0.0f; |
| 1992 | + uint32_t i; | ||
| 1994 | 1993 | ||
| 1995 | - return real; | 1994 | + i = (((uint32_t) src[1]) << 16) + src[0]; |
| 1995 | + memcpy (&r, &i, sizeof (r)); | ||
| 1996 | + return (r); | ||
| 1996 | } | 1997 | } |
| 1997 | 1998 | ||
| 1998 | /* Write a float to 4 bytes in Modbus format */ | 1999 | /* Write a float to 4 bytes in Modbus format */ |
| 1999 | void modbus_write_float(float real, uint16_t *dest) | 2000 | void modbus_write_float(float real, uint16_t *dest) |
| 2000 | { | 2001 | { |
| 2001 | - uint32_t ireal; | 2002 | + uint32_t i = 0; |
| 2002 | 2003 | ||
| 2003 | - ireal = *((uint32_t *)&real); | ||
| 2004 | - /* Implicit mask 0xFFFF */ | ||
| 2005 | - dest[0] = ireal; | ||
| 2006 | - dest[1] = ireal >> 16; | 2004 | + memcpy (&i, &real, sizeof (i)); |
| 2005 | + dest[0] = (uint16_t) i; | ||
| 2006 | + dest[1] = (uint16_t) (i >> 16); | ||
| 2007 | } | 2007 | } |