gpt4 book ai didi

c - 在没有外部链接的情况下,如何在翻译单元之间共享一组内部功能?

转载 作者:行者123 更新时间:2023-12-02 22:41:13 25 4
gpt4 key购买 nike

假设您正在编写一个库,并且您有一堆专门为自己编写的实用函数。当然,您不希望这些函数具有外部链接,这样它们就不会被您的库用户混淆(主要是因为您不会告诉外界它们的存在)

另一方面,这些功能可能会在不同的翻译单元中使用,因此您希望它们在内部共享。

让我们举个例子。您有一个执行某些操作的库,在不同的源文件中您可能需要 copy_filecreate_directory,因此您可以将它们实现为实用函数。

为了确保您的库的用户不会因为具有同名函数而意外出现链接错误,我可以想到以下解决方案:

  • 糟糕的方式:将函数复制粘贴到每个使用它们的文件中,将 static 添加到它们的声明中。
  • 不是一个好方法:将它们写成宏。我喜欢宏,但这不适合这里。
  • 给他们一个奇怪的名字,这样用户产生相同名字的机会就足够小了。这可能行得通,但会使使用它们的代码变得非常难看。
  • 我目前的工作:将它们作为 static 函数写入内部 utils.h 文件,并将该文件包含在源文件中。

现在最后一个选项几乎可以正常工作,除了它有一个问题:如果你不使用其中一个函数,至少你会收到一个关于它的警告(说函数声明为静态但从未使用过)。说我疯了,但我的代码警告是免费的。

我的做法是这样的:

实用程序.h:

...
#ifdef USE_COPY_FILE
static int copy_file(/* args */)
{...}
#endif

#ifdef USE_CREATE_DIR
static int create_dir(/* args */)
{...}
#endif
...

文件1.c:

#define USE_COPY_FILE
#define USE_CREATE_DIR
#include "utils.h"

/* use both functions */

文件2.c

#define USE_COPY_FILE
#include "utils.h

/* use only copy_file */

然而,这种方法的问题在于,随着更多实用程序的引入,它开始变得难看。想象一下,如果你有 10 个这样的函数,你需要在包含之前有 7~8 行定义,如果你需要 7~8 个这样的函数!

当然,另一种方法是使用 DONT_USE_* 类型的排除函数的宏,但是对于一个使用这些实用函数中的很少的文件,你又需要大量定义。

无论哪种方式,它看起来都不优雅。

我的问题是,您如何拥有自己库内部的函数,供多个翻译单元使用,并且避免外部链接?

最佳答案

将函数标记为 static inline 而不是 static 将使警告消失。它不会对您当前解决方案的代码膨胀做任何事情——您至少将函数的一个副本放入每个使用它的 TU 中,并且情况仍然如此。 Oli 在评论中说,链接器可能足够聪明,可以合并它们。我不是说它不是,但不要指望它 :-)

可能甚至会使膨胀变得更糟,因为它鼓励编译器实际内联对函数的调用,以便每个 TU 获得多个副本。但这不太可能,GCC 大多忽略了 inline 关键字的这一方面。它根据自己的规则内联或不内联调用。

这基本上是您可以便携地做的最好的事情。在标准 C 中没有办法定义一个符号,该符号在某些 TU(您的)的 POV 之外,但在其他 TU(您的用户)的 POV 之外。标准 C 并不真正关心什么是库,或者 TU 可能在几个步骤中链接的事实,或者静态链接和动态链接之间的区别。因此,如果您希望这些函数在您的 TU 之间实际共享,没有任何可能干扰库用户的外部符号,那么您需要做一些特定于 GCC 和/或您的静态库或 dll 格式的操作来删除符号一次库已构建,但在用户链接之前。

关于c - 在没有外部链接的情况下,如何在翻译单元之间共享一组内部功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10734735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com