我看到如下代码:(我正在处理的项目中的legecy代码)
#if __GNUC__ > 3
.ipv6_addr = {.__in6_u = {.__u6_addr32 = {0, 0, 0, 0}}}
#else
.ipv6_addr = {.in6_u = {.u6_addr32 = {0, 0, 0, 0}}}
#endif
其中“ipv6_addr”是in6_addr中struct的类型。如果__GNUC >我不明白为什么其成员in6_u会改为“ in6_u” 3.
我的问题是:为什么/当GCC版本可能影响struct in6_addr中字段的名称?
感谢。
更新:我的主机系统有GCC 4.1.2,但in6_addr定义为:
in /usr/include/netinet/in.h
/* IPv6 address */
struct in6_addr
{
union
{
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
gcc版本是:
$/usr/bin/gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --disable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-50)
答案 0 :(得分:2)
此处关注的结构定义struct in6_addr
来自C运行时库(在<netinet/in.h>
中)。 C运行时库通常与正在使用的操作系统紧密耦合,但不正在使用的C 编译器。对于将__GNUC__
定义为任何值的C编译器尤其如此(其中至少有三个:GCC,clang和icc);这些编译器设计用于许多不同的操作系统和运行时。因此,原则上,测试__GNUC__
并不会告诉您有关运行时结构定义的任何有用信息。
我怀疑这个“遗留代码”的作者在两个不同的Linux发行版上进行了测试,注意到__GNUC__
的值与<netinet/in.h>
的内容之间的意外相关性,并没有费心寻找一种更正确的方法来编译代码。
您应该用以下内容替换整个条件:
.ipv6_addr = IN6ADDR_ANY_INIT;
相关标准(POSIX.1-2008 spec for <netinet/in.h>
)要求宏IN6ADDR_ANY_INIT
可用作类型in6_addr
变量的初始值设定项,将该变量设置为IPv6通配符地址,是全位零。因此,它将具有相同的效果,而根本不需要任何#ifdef
。
为了说明此处#if __GNUC__ > 3
是错误的测试,以下是struct in6_addr
的三个不同定义,所有定义均来自您可能合理遇到的系统 both {{ 1}}和__GNUC_==3
(3.x系列现在变得有些老了,但我还是时不时地遇到它。)
__GNUC__==4
struct in6_addr
{
union
{
uint8_t __u6_addr8[16];
#if defined __USE_MISC || defined __USE_GNU
uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
#endif
} __in6_u;
};
struct in6_addr {
union {
__uint8_t __u6_addr8[16];
__uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
} __u6_addr; /* 128-bit IP6 address */
};
):netinet/in.h