Дано:
1) gcc от 4.0 до 4.4.1
2) Функцияint iconnect(in_port_t port, in_addr_t ip_address) {
...
инициализации всякие
...
int sock;
struct sockaddr_in addr;addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(ip_address);if ( connect(sock, (struct sockaddr *)&addr, sizeof (addr)) ) {
printf("ля - ля - ля\n");
}
Компилюg++-4.4 server.cpp -ffor-scope -g3 -O2 -ggdb3 -gdwarf-2 -fno-builtin -o server
-fstrict-aliasing -Wstrict-aliasing -Wunused -Wuninitialized -ftree-vrp -Wconversion
-Wall -Wextra -W -Wshadow -fstack-protector -fstack-protector-all -fbounds-check
-fstack-check -fbounds-check -ftrapv -fwrapv -Wformat;На выходе получаю WARNING
server.cpp:1250: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its value
1250 строка это - addr.sin_port = htons(port);в <in.h> прописано
/* Type to represent a port. */
typedef uint16_t in_port_t; (он же unsigned short int)
sin_port в структуре sockaddr_in типа in_addr_t
port в аргументе функции типа in_port_t
htons(port) возвращает uint16_t, аргумент у неё типа uint16_tОткуда singed int взялся???
P.S.addr.sin_port = (in_addr_t)htons(port); Не помогает.
P.P.S.
in_addr_t это uint32_t он же unsigned int
Спрашивайте в maillist'ах gcc. Это проявляется только с -Ox и не проявляется на любых версиях gcc на FreeBSD.
>Спрашивайте в maillist'ах gcc. Это проявляется только с -Ox и не проявляется
>на любых версиях gcc на FreeBSD.Ну вообще-то не просто -Ox виновата, а -Wconversion с -O2 или -O3
В мане белым по чёрному написано-Wconversion
Warn for implicit conversions that may alter a value. This includes conversions between
real and integer, like "abs (x)" when "x" is "double"; conversions between signed and
unsigned, like "unsigned ui = -1"; and conversions to smaller types, like "sqrtf (M_PI)".
Do not warn for explicit casts like "abs ((int) x)" and "ui = (unsigned) -1", or if the
value is not changed by the conversion like in "abs (2.0)". Warnings about conversions
between signed and unsigned integers can be disabled by using -Wno-sign-conversion.
У меня случай преобразования (unsigned short int) -> (unsigned int)
То есть - знака с обеих сторон нет, из меньшего в большее...
>Спрашивайте в maillist'ах gcc. Это проявляется только с -Ox и не проявляется
>на любых версиях gcc на FreeBSD.Нашёл откуда ноги растут
int main() {
unsigned short int x, y;
x = y << 8;
return 0;
}
# gcc -O0 -Wconversion test.c
# ./a.outКак говорит ISO/IEC 9899:201x, стр. 85., §6.5.7 Bitwise shift operators
> 2. Each of the operands shall have integer type.
Вот и орёт.
А дальше ещё интереснее...> 3. The integer promotions are performed on each of the operands.
> The type of the result is that of the promoted left operand.А у меня левый unsigned short :)
> If the value of the right operand is negative or is greater
>than or equal to the width of the promoted left operand, the behavior is undefined.
>[оверквотинг удален]
>int main() {
>
> unsigned short int x,
>y;
>
> x = y <<
>8;
>
>return 0;
>}во freebsd i386
htons это __byte_swap_word и аргумент до int нигде по дороге не расширяется
>>[оверквотинг удален]
>>int main() {
>>
>> unsigned short int x, y;
>> x = y << 8;
>>return 0;
>>}
>
>во freebsd i386 htons это __byte_swap_word
> и аргумент до int нигде по дороге не расширяетсяПри -O0 это
extern uint16_t htons (uint16_t __hostshort);
но при -O2 и более это тоже макрось __swap_16(x), и далее __bswap_constant_16(__x)
<in.h>
#ifdef __OPTIMIZE__
# if __BYTE_ORDER == __BIG_ENDIAN
...
# define htons(x) (x)
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
...
# define htohs(x) __bswap_16 (x)в <bits/byteswap.h>
/* Swap bytes in 16 bit value. */
#define __bswap_constant_16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
# define __bswap_16(x) \
(__extension__ \
({ register unsigned short int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_16 (__x); \
else \
__asm__ ("rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
if (__builtin_constant_p (__x))Где живёт __builtin_constant_p не нашёл
-fno-builtn не помогает, чтоб до asm дошло дело.
>Где живёт __builtin_constant_p не нашёлДык оно ж builtin, живёт в голове комплятора и ни в каком хедере не описано ;)
>>Где живёт __builtin_constant_p не нашёл
>
>Дык оно ж builtin, живёт в голове комплятора и ни в каком
>хедере не описано ;)Это понятно, смысл работы искал... нашел...
__builtin_constant_p (x) - возвращает 1 если х константа и 0 если нет.Дальше ещё веселее
Возвращение 0 не означает, что значение не является постоянным,
а лишь то, что GCC не может доказать, что она постоянно с указанным
значением опции -O.