FreeBSD 下奇怪的转换警告
Strange conversion warning under FreeBSD
我有这样的代码:
#include <sys/endian.h>
int main(){
uint64_t a = 100;
be64toh(a);
}
当我尝试将它移植到 FreeBSD 下时,我得到:
# gcc x.cc -Wall -Wconversion -Wpedantic -lstdc++ -std=c++11
x.cc: In function 'int main()':
x.cc:5:2: warning: conversion to '__uint16_t {aka short unsigned int}' from '__uint32_t {aka unsigned int}' may alter its value [-Wconversion]
be64toh(a);
^
x.cc:5:2: warning: conversion to '__uint16_t {aka short unsigned int}' from '__uint32_t {aka unsigned int}' may alter its value [-Wconversion]
x.cc:5:2: warning: conversion to '__uint32_t {aka unsigned int}' from 'uint64_t {aka long unsigned int}' may alter its value [-Wconversion]
为什么?有什么办法可以避免吗?
我可以使用 sys/endian.h 以外的其他库吗
是的,"gcc -E" 带来了答案。 be64toh 是内联函数的叠加,导致多次转换 64->32->16。我想 gcc 想告知此类转换。
(__builtin_constant_p((
a
)) ? (((__uint64_t)(__builtin_constant_p(((__uint64_t)((
a
))) & 0xffffffff) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)))) : __bswap32_var(((__uint64_t)((
a
))) & 0xffffffff)) << 32) | (__builtin_constant_p(((__uint64_t)((
a
))) >> 32) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)))) : __bswap32_var(((__uint64_t)((
a
))) >> 32))) : __bswap64_var((
a
)))
提示:使用 clang ;)
我有这样的代码:
#include <sys/endian.h>
int main(){
uint64_t a = 100;
be64toh(a);
}
当我尝试将它移植到 FreeBSD 下时,我得到:
# gcc x.cc -Wall -Wconversion -Wpedantic -lstdc++ -std=c++11
x.cc: In function 'int main()':
x.cc:5:2: warning: conversion to '__uint16_t {aka short unsigned int}' from '__uint32_t {aka unsigned int}' may alter its value [-Wconversion]
be64toh(a);
^
x.cc:5:2: warning: conversion to '__uint16_t {aka short unsigned int}' from '__uint32_t {aka unsigned int}' may alter its value [-Wconversion]
x.cc:5:2: warning: conversion to '__uint32_t {aka unsigned int}' from 'uint64_t {aka long unsigned int}' may alter its value [-Wconversion]
为什么?有什么办法可以避免吗?
我可以使用 sys/endian.h 以外的其他库吗
是的,"gcc -E" 带来了答案。 be64toh 是内联函数的叠加,导致多次转换 64->32->16。我想 gcc 想告知此类转换。
(__builtin_constant_p((
a
)) ? (((__uint64_t)(__builtin_constant_p(((__uint64_t)((
a
))) & 0xffffffff) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) & 0xffffffff)) >> 16)))) : __bswap32_var(((__uint64_t)((
a
))) & 0xffffffff)) << 32) | (__builtin_constant_p(((__uint64_t)((
a
))) >> 32) ? (((__uint32_t)((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) & 0xffff))) << 16) | ((__uint16_t)(__builtin_constant_p(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16) ? (__uint16_t)(((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)) << 8 | ((__uint16_t)(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)) >> 8) : __bswap16_var(((__uint32_t)(((__uint64_t)((
a
))) >> 32)) >> 16)))) : __bswap32_var(((__uint64_t)((
a
))) >> 32))) : __bswap64_var((
a
)))
提示:使用 clang ;)