如何在C89/C99编译环境下用单行代码初始化sockaddr_in结构体
sockaddr_in 单行初始化正确方案
已知前提
使用C89/C99编译器时,以下两行代码可正常完成sockaddr_in初始化:
struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY}; server.sin_addr.s_addr = inet_addr("127.0.0.1");
以下写法均无法正常运行:
// 错误:多余参数会被用于初始化sin_zero,无法修改sin_addr的s_addr字段 struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY, inet_addr("127.0.0.1") }; // 错误:先给sin_addr赋值了INADDR_ANY,后续指定初始化器位置错误导致覆盖失败 struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY, .sin_addr.s_addr = inet_addr("127.0.0.1") }; // 错误:Windows下IN_ADDR为union,第一个成员是字符数组,仅会将返回值的低8位赋值给数组首元素 struct sockaddr_in server = { AF_INET, htons(27015), {inet_addr("127.0.0.1")}, {0} };
sockaddr_in 结构体定义参考(Windows平台):
typedef struct sockaddr_in { short sin_family; USHORT sin_port; IN_ADDR sin_addr; CHAR sin_zero[8]; } SOCKADDR_IN, *PSOCKADDR_IN;
注:Windows平台下IN_ADDR为联合体,首个成员为字符数组,直接传入整数初始化会导致值异常。
正确写法
1. C99及以上编译器(推荐,跨平台兼容)
使用C99支持的指定初始化器,明确给对应字段赋值,完全避开初始化顺序和联合体成员匹配问题:
struct sockaddr_in server = { .sin_family = AF_INET, .sin_port = htons(27015), .sin_addr.s_addr = inet_addr("127.0.0.1") };
未显式初始化的成员(包括sin_zero数组)会被默认初始化为0,完全符合socket API的调用要求。
2. 仅支持C89的编译器
C89不支持指定初始化器,且受Windows平台IN_ADDR联合体的成员顺序限制,没有纯标准的单行初始化方案,如果必须写在同一行,可以用逗号表达式合并声明和赋值:
struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY }, server.sin_addr.s_addr = inet_addr("127.0.0.1");
该写法本质等价于原始的两行实现,仅为排版上的单行。
内容的提问来源于stack exchange,提问作者vengy
相关产品推荐
相关产品推荐

