There is a very simple function:
/******** func.c **********/
#include <netinet/in.h>
uint16_t my_htons(uint16_t hostshort)
{
return htons(hostshort);
}
/**************************/
$ cc func.c -Wconversion -Werror -c -o func.o
Exit 0
$ cc func.c -O1 -Wconversion -Werror -c -o func.o
cc1: warnings being treated as errors
func.c: In function ‘my_htons’:
func.c:5: error: conversion to ‘short unsigned int’ from ‘int’ may alter
its value
Exit 1
Adding -E flag I get the following code:
...
# 2 "func.c" 2
uint16_t my_htons(uint16_t hostshort)
{
return (__extension__ ({ register unsigned short int __v, __x =
(hostshort); if (__builtin_constant_p (__x)) __v = ((((__x) >> 8) &
0xff) | (((__x) & 0xff) << 8)); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }));
}
Is there anything (smart) that either I or gcc or glibc/linux can do
about this?
No type-casts in *my* code help.
The warning seems to be uncalled for in this case, because I don't see
explicit 'int' type anywhere in the expanded code.
P.S. the code seems to be coming from /usr/include/bits/byteswap.h,
__bswap_16() macro in this way:
======= netinet/in.h =======
#ifdef __OPTIMIZE__
/* We can optimize calls to the conversion functions. Either nothing has
to be done or we are using directly the byte-swapping functions which
often can be inlined. */
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
so these functions are all just identity. */
# define ntohl(x) (x)
# define ntohs(x) (x)
# define htonl(x) (x)
# define htons(x) (x)
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define ntohl(x) __bswap_32 (x)
# define ntohs(x) __bswap_16 (x)
# define htonl(x) __bswap_32 (x)
# define htons(x) __bswap_16 (x)
# endif
# endif
#endif
--
Andriy Gapon