为什么许多C函数使用指针传递数据而不是使用"return"?

Mel*_*lab 10 c function

这或多或少是关于方法论和基本原理的问题.在为Linux编写各种内核模块时,我对我认为是一种设计函数的笨重方式感到困惑.例如,要检索给定其路径的文件的inode,我必须使用以下内容:

struct inode *inode;
struct path path;
kern_path(path_name, LOOKUP_FOLLOW, &path);
inode = path.dentry->d_inode;
Run Code Online (Sandbox Code Playgroud)

为什么不只是一个功能如下:

struct inode inode;
struct path path = kern_path(path_name, LOOKUP_FOLLOW);
inode = path.dentry->d_inode;
Run Code Online (Sandbox Code Playgroud)

看起来更直观.

Cor*_*lks 15

而且你会怎么做int那个kern_path返回

函数能够返回某种错误代码非常重要,这样用户就可以确保函数成功.有两个明显的选择:

  1. 返回错误代码.

    这意味着您必须将您想要返回的其他值作为参数.

  2. 返回值.

    这意味着您必须将错误代码作为参数.

由于您只能在C中返回1个值,因此您必须将某些内容作为参数,因为最终您需要向用户返回两个内容(错误代码和值).

  • 有人会争辩说,返回值并在参数中传递错误可以更容易确保不忽略错误.当然,有一个`__attribute __((warn_unused_result))`,但是人们通常都懒得不能一直使用它. (2认同)

Bas*_*tch 7

内核是一个具有特殊约束的C程序.特别是,不允许调用堆栈很深(IIRC,它限制为4K字节).

当你返回a时struct,ABI(参见x86-64 ABI ...)强制要求(除了两个单词中的一些 struct拟合)返回的struct是通过堆栈.所以这样的风格会有利于相当大的堆栈帧,因此更容易满足堆栈限制.

BTW,通常的样式是返回一些整数错误代码,并修改参数指针指向的数据.

在x86-64/Linux上返回两个标量值(整数,指针,枚举,双精度等)的结构绝对值得,看看这个.


Ami*_*mit 2

这样做的好处是可以减少来回复制内存块的次数。

使用这种方法允许调用的函数仅修改传入结构的某些部分,并且根本不复制内存。