这行 C 代码是做什么的?

7

我刚刚在阅读一个名为sofia-sip的库,这段代码出现在代码示例中:

msg_iovec_t iovec[2] = {{ 0 }};

供参考,以下是 msg_iovec_t 的定义:

struct iovec {
    void *iov_base;     // Pointer to data.
    size_t iov_len;     // Length of data.
};

2
非常离题,但是“_t”后缀不是为 POSIX 类型保留的吗?高度建议不要将其附加到您自己的类型名称上。 - JustSid
2
@JustSid - 是的可能 - aaz
2个回答

8

这将在堆栈上创建了一个包含两个iovec结构的数组,并将两个数组元素的所有成员初始化为零。

初始化程序{{ 0 }}仅为第一个数组元素的第一个成员iovec[0].iov_base提供了一个明确的值:提供的值0会隐式转换为null指针。

第一个数组元素的其他成员和其他数组元素也被隐式初始化:指向null的指针和算术类型为0。

该行可以等价地写为

msg_iovec_t iovec[2] = { 0 };

这是零初始化整个对象的最短标准方式,因此它是惯用语。一些编译器可能会接受空初始化列表{}作为扩展。一些编译器可能会对此形式发出警告,并要求足够的大括号来指定第一个非聚合成员(例如原始行中的两对)。

其效果类似于

msg_iovec_t iovec[2];
bzero(iovec, sizeof iovec);

除了更加干净和便携之外,因为空指针并不一定填充了零字节,所以要小心。


1
一个零的原因是,历史上并不是所有编译器都同意什么是“足够的”。 - Bo Persson
1
另外,bzero(&myptr, sizeof(myptr)); 不等同于 myptr = 0; (myptr = NULL;)。 - Conrad Meyer
1
@aaz:{} 不是 有效的 C 语言,它只适用于 C++。{0} 是 C 语言中最短的通用零初始化器。 - R.. GitHub STOP HELPING ICE
谢谢。@Bo,@R. - 你们说得对,语法要求非空列表(虽然gcc可以在没有-pedantic的情况下接受它)。@Conrad - 这就是我所说的“类似”的意思 - 已经澄清了。 - aaz
2
在代码中看到双大括号的原因是GCC的作者成功地破坏了通用零初始化惯用法{ 0 }的支持,通过发出警告来初始化多级聚合体(比如结构体数组)。通常人们会使用{ 0 },但由于有警告,所以必须使用{{ 0 }} - AnT stands with Russia
显示剩余2条评论

2

第一个括号声明正在初始化数组。第二个声明结构体的iovec第一个字段:iov_base正在被初始化为NULL值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接