问题
I was asked a very interesting question during a C interview: How can you implement a function f() in such a way that it can only be called from a particular g() function. If a function other than g() tries to call f() it would result in a compiler error.
At first, I though this could be done with function pointers and I could get close to blocking the call at runtime. But I was not able to think of a compile time strategy. I don't even know if this is possible using ansi C.
Does anyone have any idea?
回答1:
Here's one way:
int f_real_name(void)
{
...
}
#define f f_real_name
int g(void)
{
// call f()
}
#undef f
// calling f() now won't work
Another way, if you can guarantee that f()
and g()
are the only functions in the file, is to declare f()
as static
.
EDIT: Another macro trick to cause compiler errors:
static int f(void) // static works for other files
{
...
}
int g(void)
{
// call f()
}
#define f call function
// f() certainly produces compiler errors here
回答2:
Put g() and f() in the same module, and declare f() as static. The static keyword makes f() available only to functions in the same module, or source file.
You might also want to mention that no other methods should be allowed in the module with f() and g(), otherwise they could call f().
PS - I really think Chris Lutz' answer is actually the best. It mentions this approach, but also a clever macro renaming that works with fewer environmental conditions (does not require the module file specifically for these two functions).
Note also that with a macro, you could do the following:
#define f() f_should_not_be_called_by_anything_except_g
Which would present a nice error message, and auto-completers (like Visual Studio) would show that tip when the user types f().
回答3:
You can make module-private functions with the static
keyword:
static void func(void)
{
// ...
}
Then, func()
can only be called by other functions defined in the same file (technically, the same translation unit: other functions whose definitions are included by a #include
directive can still access it). func
is said to have internal linkage. All other functions (that is, without the static
keyword) are said to have external linkage.
Beyond that, no, there is no way to make functions inaccessible. You can use macros to change the name of the function, but other code can always still access it with the appropriate name.
回答4:
Place f()
and g()
in the same source file, declare f()
static.
回答5:
An option for GCC is to use nested functions. While it's not standard C, it works quite well.
回答6:
It is only possible coincidentally.
If functions f() and g() are both in the same source file, and there are no other functions in the file, and if g() never returns the function pointer to f() to any of its callers, then making f() static will do the job.
If other functions must appear in the same source file, placing f() at the bottom of the file as a static function, and only defining g() immediately after it would achieve more or less the same effect - though if you didn't tell the compiler to generate errors on 'missing declarations' other functions could call it with warnings.
#include <stdio.h>
extern void g(void); /* in a header */
/* Other functions that may not call f() go here */
static void f(void)
{
puts("X");
}
void g(void)
{
f();
}
Clearly, this technique cannot be extended reliably to another pair of functions in the same file - x() and y() - such that x() and only x() can call y() while g() and only g() can call f() at the same time.
However, normally you would rely on the programmers' discipline and simply make f() static in the source file, along with a comment that only g() may call it, and then discipline anyone who modifies the code so that a function other than g() calls f().
来源:https://stackoverflow.com/questions/1401781/how-to-implement-a-private-restricted-function-in-c