如何在C中实现"私有/限制"功能?

lui*_*roy 28 c function-pointers function

在C采访中我被问到一个非常有趣的问题:如何以一种只能从特定的g()函数调用它的方式实现函数f().如果g()以外的函数试图调用f(),则会导致编译器错误.

起初,我虽然可以使用函数指针完成,但我可以在运行时接近阻塞调用.但我无法想到编译时策略.我甚至不知道使用ansi C是否可行.

有谁有想法吗?

Chr*_*utz 39

这是一种方式:

int f_real_name(void)
{
    ...
}

#define f f_real_name
int g(void)
{
    // call f()
}
#undef f

// calling f() now won't work
Run Code Online (Sandbox Code Playgroud)

另一种方式,如果你能保证f()g()是唯一的功能,在文件中,正在申报f()static.

编辑:导致编译器错误的另一个宏技巧:

static int f(void) // static works for other files
{
    ...
}

int g(void)
{
    // call f()
}
#define f call function

// f() certainly produces compiler errors here
Run Code Online (Sandbox Code Playgroud)

  • 当然我们可以调用`f_real_name()`.我们也可以调用`printf()`,`malloc()`和许多其他很好的函数,但它与调用`f()`有什么关系呢? (3认同)
  • 但是,您仍然可以调用f_real_name(). (2认同)
  • 有人愿意解释一下否决票吗?我知道这不是OP想要的,但它_确实_满足他的标准。 (2认同)

Wal*_*t W 27

将g()和f()放在同一个模块中,并将f()声明为static.static关键字使f()仅可用于同一模块或源文件中的函数.

您可能还想提一下,在f()和g()模块中不允许其他方法,否则它们可以调用f().

PS - 我真的认为Chris Lutz的答案实际上是最好的.它提到了这种方法,但也是一种巧妙的宏重命名,它可以在较少的环境条件下工作(不需要专门用于这两个功能的模块文件).

另请注意,使用宏,您可以执行以下操作:

#define f() f_should_not_be_called_by_anything_except_g
Run Code Online (Sandbox Code Playgroud)

这将提供一个很好的错误消息,并且自动完成程序(如Visual Studio)将在用户键入f()时显示提示.


Ada*_*eld 11

您可以使用static关键字创建模块私有函数:

static void func(void)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后,func()只能由同一文件中定义的其他函数调用(从技术上讲,相同的翻译单元:#include指令包含的其他函数仍然可以访问它). func据说有内部联系.所有其他功能(即没有static关键字)据说具有外部链接.

除此之外,不,没有办法使功能无法访问.您可以使用宏来更改函数的名称,但其他代码仍然可以使用适当的名称访问它.


Joh*_*kin 8

f()g()同一个源文件中,声明f()静态的.

  • 任何可以编辑源函数的人都可以克服*any*scheme来制作私有的东西. (20认同)

out*_*tis 8

GCC的一个选项是使用嵌套函数.虽然它不是标准的C,但它的效果非常好.