- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我看到如下代码:(我正在处理的项目中的遗留代码)
#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系列现在有点老了,但我还是时不时碰到)。
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
):struct in6_addr {
union {
UCHAR Byte[16];
USHORT Word[8];
} u;
};
关于c - GCC 4 中的 in6_addr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18922569/
我是一名优秀的程序员,十分优秀!