为啥 Linux NETLINK 手册页提供 C++ 示例而不提供 C?

Posted

技术标签:

【中文标题】为啥 Linux NETLINK 手册页提供 C++ 示例而不提供 C?【英文标题】:Why does Linux NETLINK man page provide C++ examples but not C?为什么 Linux NETLINK 手册页提供 C++ 示例而不提供 C? 【发布时间】:2019-12-20 22:56:50 【问题描述】:

我处理了netlink API 并检查了它的手册页netlink(3) 和netlink(7)。 突然间我遇到了这样的结构:

struct msghdr msg;

msg =  &sa, sizeof(sa), &iov, 1, NULL, 0, 0 ;

我在 C 中尝试过,但它给出了错误:

错误:“”标记之前的预期表达式

显然是c++(我不知道什么标准)。 当然很明显,Netlink 是一个 API,没有特定的语言绑定。但这是 C 实现,我看到的所有关于 C API 的 MAN 页面都有纯 C 示例。为什么没有关于示例中使用的语言的注释?这种做法是为了什么,为什么这不是 f.e.在 Python 上还是什么?


UPD:我认为这不是 MAN 页面中的拼写错误或无意错误。还有一些其他地方使用了这个 C++ 特性,例如:

struct iovec iov =  buf, sizeof(buf) ;
struct sockaddr_nl sa;
struct msghdr msg;
struct nlmsghdr *nh;

msg =  &sa, sizeof(sa), &iov, 1, NULL, 0, 0 ;
len = recvmsg(fd, &msg, 0);

for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
     nh = NLMSG_NEXT (nh, len)) 
...

看起来像是有意识地选择了 C++。

【问题讨论】:

问题是举一个小例子并断言它适用于更广泛.. 问题真的是“为什么 这个特定的 [netlink] 手册页 提供了一个不在本地编译为 C?” (也许是提交错误报告。) @Eljay 可以初始化,但不能这样赋值。 我认为这只是一个反常现象。通常 Unix 手册页使用 C 语法,我认为这本书的作者搞砸了。 他可能是想写struct msghdr msg = ... ;,但出于某种原因,他将它们分成了单独的语句。 示例在C++ 中编译,但不是纯C++ 代码(看起来有点不同)。我想说这是C 代码,带有一个小的 C++ 特性。这里是equivalent examle。基本上是文档中的错误,它是如此轻松以至于被所有人忽略。 【参考方案1】:

为什么 Linux 手册页提供 C++ 示例而不提供 C?

Linux 手册页提供了 C 示例。他们不提供 C++ 示例。

我在 C 中尝试过,但它给出了错误:

这是文档中的错误。它的意思是:

struct msghdr msg =  &sa, sizeof(sa), &iov, 1, NULL, 0, 0 ;

我相信您可以在 linux-man 邮件列表上发布错误报告。

为什么没有说明示例中使用的语言?

如on the project homepage 所述,Linux 手册页记录了 Linux 内核和 C 库接口。 Linux 内核是用 C 语言编写的(主要是 there is some assembly, etc.)。因此,Linux 手册页以 C 编程语言提供示例。

这种做法是为了什么,为什么这不是 f.e.在 Python 上还是什么?

实践是在Linux的开发中使用C语言。它不是 Python 或任何其他语言,因为 Linux 内核是用 C 编程语言编写的。 Linux 内核是用 C 编程语言编写的,因为 Linux 内核的创建者 Linus Torvalds 很久以前就决定用 C 编程语言编写内核。

对于内核开发人员来说,使用内核自己编写的语言为用户空间程序分发内核接口 API 是最简单的,因此他们不必为用户空间程序用另一种编程语言重写它。例如,它们还可以使用用户空间在内核本身中使用的相同头文件。例如,这可以减少错误和工作量等。因此,内核开发人员最容易使用用 C 编程语言编写的示例来提供文档。

【讨论】:

这个具体的例子,struct msghdrsendmsg(),以及其他使用的 API 来自用户空间 C 库。所以它在 C 中真的不是因为内核在 C 中,而是因为正在使用的用户空间库是 C 库。那些用 C 语言编写的用户空间库和头文件当然与用 C 语言编写的内核有关。 即使在更正之后它仍然是错误的。 msghdr 中成员的顺序(以及其他中间成员的缺席)是未指定的。您需要使用指定的初始化程序或分配成员才能正确使用msghdr @KamilCuk 感谢您的澄清!但是关于错误的说法有些令人怀疑。更新了我的问题。 我不明白,你为什么会怀疑呢? Linux 手册页有意不想提供 C++ api。标头是用 C 编写的,extern "C" 可以在 netlink 标头中丢失,recvmsg(或由 netlink 导出的任何其他函数)函数不会根据 C++ 进行损坏。

以上是关于为啥 Linux NETLINK 手册页提供 C++ 示例而不提供 C?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 C++11 安装手册页

Linux用户与内核空间交互—netlink

Linux用户与内核空间交互—netlink

显示文本,如手册页

C 语言网络编程 — PF_NETLINK sockets

C 语言网络编程 — PF_NETLINK sockets