gpt4 book ai didi

c - GCC 4 中的 in6_addr

转载 作者:太空狗 更新时间:2023-10-29 12:18:15 24 4
gpt4 key购买 nike

我看到如下代码:(我正在处理的项目中的遗留代码)

#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”是 struct in6_addr 的类型。我不明白如果 __GNUC> 3,为什么它的成员 in6_u 会变成“in6_u”。

我的问题是:为什么/何时 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)

最佳答案

关注这里的结构体定义,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;

IN6ADDR_ANY_INIT相关标准 ( POSIX.1-2008 spec for <netinet/in.h> ) 要求可用作 in6_addr 类型变量的初始值设定项,将该变​​量设置为全零位的 IPv6 通配符地址。所以它会产生同样的效果而不需要任何 #ifdef完全没有。


为了说明#if __GNUC__ > 3在这里应用是错误的测试,这里是 struct in6_addr 的三个不同定义,全部取自您可能会合理地遇到两者的系统 __GNUC_==3__GNUC__==4 (3.x系列现在有点老了,但我还是时不时碰到)。

GNU libc 2.17

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;
};

NetBSD 6.1

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 */
};

Windows 7(官方SDK;反倒不提供netinet/in.h):

struct in6_addr {
union {
UCHAR Byte[16];
USHORT Word[8];
} u;
};

关于c - GCC 4 中的 in6_addr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18922569/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com