警告:'memset' 总是会溢出 [-Wfortify-source]

Mik*_*rov 0 c memset

尝试操纵 中的 IPv6 地址struct sin6_addr,例如清理它:

struct sockaddr a;
memset(&(((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr), 0, 16);
printf("SIZEOF: %lu\n", sizeof((((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr)));
Run Code Online (Sandbox Code Playgroud)

并面临警告:

1.c:34:2: warning: 'memset' will always overflow; destination buffer has size 8, but size argument is 16 [-Wfortify-source]
        memset(&(((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr), 0, 16);
Run Code Online (Sandbox Code Playgroud)

同时printf("SIZEOF...")返回16个字节,那么空间应该足够了吧?

另外,如果我这样做:

struct sockaddr a;
struct in6_addr aa;
aa = ((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr;
memset(&aa, 0, 16);
Run Code Online (Sandbox Code Playgroud)

没有显示任何警告。我做错了什么?

UPD。修复了 printf() 中的一个问题

SKi*_*SKi 5

Attie 已经给出了完整的答案,但这提供了存储套接字地址的替代方法:

struct sockaddr_storage
Run Code Online (Sandbox Code Playgroud)

socket(7) 的手册页内容如下:

套接字 API 提供数据类型 struct sockaddr_storage。
该类型适合容纳所有
受支持的特定于域的套接字地址结构;它
足够大并且正确对齐。

sockaddr_storage 结构在必须
以通用方式处理套接字地址的程序中非常有用(例如,必须同时处理 IPv4 和 IPv6 套接字地址的程序)。

所以代替这个:

struct sockaddr a;
Run Code Online (Sandbox Code Playgroud)

你应该使用这个:

struct sockaddr_storage a;
Run Code Online (Sandbox Code Playgroud)

为大多数不同的地址类型获得足够的空间。