为什么在许多驱动程序上,函数的返回值都是用变量处理的?

时间:2018-08-28 16:55:20

标签: c linux-kernel kernel-module

我在很多驱动程序代码中都看到

static rettype fun(argtype arg) {
    rettype ret;
    // do some stuff and change ret accordingly
    return ret;
}

在直接返回值或在可能的情况下跳转时不能更快地处理吗?这样,您可以节省返回值和至少需要做的ret分配的空间。我很困惑,每一个帮助都会很好。谢谢。

1 个答案:

答案 0 :(得分:2)

通常,看起来很复杂的代码结构嵌套在其中,例如:

Calculate some things, look up some things.
if (one thing)
{
    Get some more things.
    if (another thing)
        …
}
else
{
    Get different things.
    if (that thing)
        …
    else
        …
            …
                if (yet another decision)
                    retval = SURE_THAT_IS_FINE;
                else
                    …
            …
        …
    …
}

完全等同于用retval =代替return SURE_THAT_IS_FINE的相同代码。这是因为任何质量正常的编译器都会构造代码流程图。无论代码在嵌套结构的深处有return语句,还是仅仅从嵌套结构中掉出来,接下来要做的就是从函数返回。即使有了赋值语句,编译器也会看到retval仅用于从函数中返回一个值,因此编译器将优化分配—它只会将值放在适当的位置以从函数中返回它。函数,而不是将其实际写入分配给retval的单独内存中。

因此,就编译器和生成的代码而言,这两种选择之间没有区别。那为什么我们要选一个呢?

软件变得越来越复杂,在使用复杂的代码时,人们容易犯错误。减少错误的一种方法是创建要遵循的常规模式。如果我们找出有效的模式,并且在编写代码时遵循这些模式,那么我们就可以免除编写或修改代码时对所有代码进行分析的某些需求;我们可以遵循该模式,而不必追溯所有代码。在我们脑海中多次编码以弄清楚。编程并不需要我们遵循模式,但是使用模式是使我们的工作更轻松或更好的一种工具。

在这种情况下,驱动程序开发人员可能已经建立了一种始终分配retval并进入驱动程序例程末尾的模式。在某些驱动程序中,return之前可能会有一些最终处理代码。例如,可能有代码释放已分配的资源,或者如果返回了错误代码,则可能会触发某些内容的代码。即使您查看的特定驱动程序中没有这样的代码,其他驱动程序中也可能没有。遵循始终掉到例程末尾而不是直接返回的模式的目的是确保始终执行而不是绕过该最终处理代码。

那只是一个例子。使用此模式可能还有其他原因。