【问题标题】:Purpose of static function in C [duplicate]C中静态函数的目的[重复]
【发布时间】:2013-12-23 00:04:00
【问题描述】:

我知道静态函数的名称仅在声明它的文件(翻译单元)中可见。这使得封装成为可能。

但是静态函数通常是在源文件中声明的,因为如果你在头文件中声明,你最终会得到它的多个实现(我认为这不是static的意图)。

例子:

ma​​in.c

#include "functions.h"

int main()
{
    FunctionA();
    FunctionB(); // Can't call regardless of "static".
    return 0;
}

functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

void FunctionA();

#endif /* FUNCTIONS_H */

functions.c

#include "functions.h"
#include <stdio.h>

static void FunctionB(); // Same whether "static" is used or not.

void FunctionA()
{
    printf("A");
}

void FunctionB()
{
    printf("B");
}

那么static 什么时候有用?

【问题讨论】:

  • 它大致相当于 OOP 中的 private 方法 - 有时您不希望除您自己的库之外的任何其他人都可以使用内部函数。
  • 要查看用途,您需要拥有多个 .c 文件。在两者中实现一个名为private_helper() 的函数,看看会发生什么。
  • 当你想从functions.c中的FunctionA调用FunctionB时。 static 用于未导出的函数。

标签: c function static


【解决方案1】:

static 表示该函数具有内部链接。这意味着它不会与其他文件(翻译单元)中相同标识符的其他用途相关联。

例如,假设在Tree.c 中我有一个对树结构进行操作的函数,并且我有一些名为UpdateNode 的本地子例程对树的一部分进行操作。进一步假设在List.c 中,我有一个对List 结构进行操作的函数,并且它还有一些称为UpdateNode 的局部子例程,它仅用于List 结构,而不用于Tree 结构。

如果我将这两个子例程都保留为外部链接,则链接器会抱怨多个定义。通过将它们标记为与static 的内部链接,可以避免此问题。

【讨论】:

    【解决方案2】:

    在以下情况下很有用:

    1. 该函数不应在翻译单元之外可见。
    2. 应将函数的可见性视为“隐藏”(使用动态链接器时)。
    3. 让编译器警告未使用的函数。
    4. 内联普通函数,在这种情况下,静态函数在标题中定义。用于 C99 之前的代码的宏的更好替代方案。

    或以上任何一种的组合。可能还有一些我没有立即想到的事情。

    【讨论】:

      【解决方案3】:

      除了所有答案之外,我还想补充一下MISRA C 对静态关键字的看法。

      规则 8.8static 存储类说明符应在所有 具有内部链接的对象和函数的声明

      标准规定,如果一个对象或函数用 extern 存储类说明符和对象的另一个声明 或函数已经可见,则链接是由 较早的声明。这可能会令人困惑,因为它可能是 预计 extern 存储类说明符会创建外部 连锁。 static 存储类说明符因此应为 一致地应用于具有内部链接的对象和函数。

      还有这个

      规则 8.10 内联函数应使用静态存储类声明

      如果一个内联函数声明了外部链接但没有 在同一个翻译单元中定义,行为未定义。

      换句话说,尽可能使用static关键字

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-13
        • 2011-07-18
        • 1970-01-01
        相关资源
        最近更新 更多