htons(), gcc и типы :-/ нефкурю... , pavlinux, 08-Окт-09, 03:06 [смотреть все]Дано: 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 |
- htons(), gcc и типы :-/ нефкурю... , аноним, 17:49 , 08-Окт-09 (1)
Спрашивайте в maillist'ах gcc. Это проявляется только с -Ox и не проявляется на любых версиях gcc на FreeBSD.
- htons(), gcc и типы :-/ нефкурю... , pavlinux, 00:03 , 09-Окт-09 (2)
>Спрашивайте в 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) То есть - знака с обеих сторон нет, из меньшего в большее...
- htons(), gcc и типы :-/ нефкурю... , pavlinux, 03:09 , 09-Окт-09 (3)
>Спрашивайте в 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.
- htons(), gcc и типы :-/ нефкурю... , gpl77, 10:25 , 09-Окт-09 (4)
>[оверквотинг удален] >int main() { > > unsigned short int x, >y; > > x = y << >8; > >return 0; >} во freebsd i386 htons это __byte_swap_word и аргумент до int нигде по дороге не расширяется
- htons(), gcc и типы :-/ нефкурю... , pavlinux, 16:54 , 09-Окт-09 (5)
>>[оверквотинг удален] >>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 дошло дело.
- htons(), gcc и типы :-/ нефкурю... , const86, 00:20 , 10-Окт-09 (6)
>Где живёт __builtin_constant_p не нашёл Дык оно ж builtin, живёт в голове комплятора и ни в каком хедере не описано ;)
- htons(), gcc и типы :-/ нефкурю... , pavlinux, 01:47 , 10-Окт-09 (7)
>>Где живёт __builtin_constant_p не нашёл > >Дык оно ж builtin, живёт в голове комплятора и ни в каком >хедере не описано ;) Это понятно, смысл работы искал... нашел... __builtin_constant_p (x) - возвращает 1 если х константа и 0 если нет.
Дальше ещё веселее Возвращение 0 не означает, что значение не является постоянным, а лишь то, что GCC не может доказать, что она постоянно с указанным значением опции -O.
|