allowing a function to be called only from a specific function

J

junky_fellow

Hi,

Is there any way, by which we can limit a specific function to be
called
only from a specific function ? I dont know the advantage of this.
Someone
asked this question from me in an interview.

thanks for any help ...
 
R

Richard Heathfield

(e-mail address removed) said:
Hi,

Is there any way, by which we can limit a specific function to be
called
only from a specific function ? I dont know the advantage of this.
Someone
asked this question from me in an interview.

thanks for any help ...

For ease of reference, let's call them foo() and bar(), and you want it to
be impossible to call bar() except from foo().

Put foo() and bar() in foo.c. Make bar() static:

static int bar(double *, void ***, char, unsigned long);

Compile foo.c to an object file, and publish the object file, together with
the interface spec (foo.h, which need not and indeed should not even
mention bar() at all), to your users. Don't give them the source file. :)
They don't need it, and it'd only get them poking around in the guts of
bar(), which is presumably what you're trying to prevent.

Provided you do not export bar()'s address from foo() - and if you don't
know what I'm talking about, it's extremely unlikely that you'd do this by
accident! - then you will now only be able to call bar() from foo().
 
J

junky_fellow

(e-mail address removed) said:



be impossible to call bar() except from foo().

Put foo() and bar() in foo.c. Make bar() static:

static int bar(double *, void ***, char, unsigned long);

Compile foo.c to an object file, and publish the object file, together with
the interface spec (foo.h, which need not and indeed should not even
mention bar() at all), to your users. Don't give them the source file. :)
They don't need it, and it'd only get them poking around in the guts of
bar(), which is presumably what you're trying to prevent.

Provided you do not export bar()'s address from foo() - and if you don't
know what I'm talking about, it's extremely unlikely that you'd do this by
accident! - then you will now only be able to call bar() from foo().
In fact, I also suggested the same thing, but he said that there could
be
multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and
f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?
 
M

mark_bluemel

In fact, I also suggested the same thing, but he said that there could
be multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?

Not within the specification of the language, I wouldn't think.

There could be platform-specific ways, involving all manner of horrid
sub-rosa knowledge.
 
S

santosh

In fact, I also suggested the same thing, but he said that there could
be multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?

I think you want C++.
 
C

Chris Dollin

Not within the specification of the language, I wouldn't think.

/* insert any necessary forward declarations here
(but, of course, not for f1)
*/

f3() { ... }

f4() { ... }

f5() { ... }

static f1() { ... }

f2() { ... f1() ... }
 
D

Duncan Muirhead

Not within the specification of the language, I wouldn't think.

There could be platform-specific ways, involving all manner of horrid
sub-rosa knowledge.
Off Topic:
Or you could use a specific compiler's language extension, for example gcc
allows nested functions.
 
R

Richard Tobin

In fact, I also suggested the same thing, but he said that there
could be multilpe functions (say f1(), f2(), f3(), f4() etc) in the
some file and f1() should be allowed to be called only from f2() and
not from any other function in that file or in some other file. Is
there any way of doing it ?

It's hard to make much sense of this without knowing the purpose of
the constraint. If someone can change f3 so that it tries to call f1,
they can edit the rest of the file to remove any mechanism you have
used to prevent it (unless you have some magic editor that only allows
you to change part of the file, in which case it could enforce the
rule about calling f1 too).

If you suppose that the aim is to prevent someone inadvertently calling
it in a context where it would be inappropriate, you might do it by
naming the function "f1_but_do_not_call_this_function", and putting
#define f1 f1_but_do_not_call_this_function at the beginning of f2
and #undef f1 at the end of it.

I would probably just put a comment on f1 describing the circumstances
in which it was safe to call it.

-- Richard
 
E

Eric Sosman

[...]
In fact, I also suggested the same thing, but he said that there could
be
multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and
f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?

Make f1() static and place it next-to-last in the file,
right before f2(). Threaten to crush the gizzards of anyone
who writes a forward declaration of f1() earlier in the file.

Make f1() static and place it first in the file, right
before f2(). Follow f2 with `#define f1 >* die, slime! *<'
and threaten to crush the gizzards of anyone who writes an
`#undef f1'.

Give f1() external linkage, publish its declaration in an
appropriate header file, and threaten to crush the gizzards
of anyone who calls it from anyplace except within f2().

There's nothing I can think of that doesn't ultimately
rest on someone's unwillingness to have his gizzards crushed.
Compilers are not nannies.
 
C

Christopher Benson-Manica

In fact, I also suggested the same thing, but he said that there could
be
multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and
f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?

Not really, but you could do something like this anyway - document
f1() to be called by a macro INVOKE_F1 and only define the macro to
correctly invoke f1() inside f2():

#include <stdio.h>
#include <stdlib.h>

#define INVOKE_F1() fprintf( stderr, "Invalid invocation of f1\n" ); abort();

void f1() {
printf( "Invoked f1()\n" );
}

void f2() {
#undef INVOKE_F1
#define INVOKE_F1() f1()
INVOKE_F1();
#undef INVOKE_F1
#define INVOKE_F1() fprintf( stderr, "Invalid invocation of f1\n" ); abort();
}

void f3() {
INVOKE_F1();
}

int main(void) {
f2();
f3();
return 0; /* Not reached. */
}
 
M

Malcolm

In fact, I also suggested the same thing, but he said that there could
be
multilpe functions (say f1(), f2(), f3(), f4() etc) in the some file
and
f1() should be allowed to be called only from f2() and not from any
other function in that file or in some other file. Is there any way of
doing it ?
The interviewer is out of date.
Some old-time C compilers allowed the use of local function definitons

int foo()
{
int bar(int, int);

return bar(1,2);
}

int bar()
int x,
int y
{
return 0;
}

bar is now local to foo(). I think I've got that right. It never caught on
and now static is the universally-approved way of restricting access to a
function.
 
O

Old Wolf

Chris said:
f3() { ... }

f4() { ... }

f5() { ... }

static f1() { ... }

f2() { ... f1() ... }

f3() can still write:
int f1();

to declare f1, and then call it.
 
K

Keith Thompson

Malcolm said:
The interviewer is out of date.
Some old-time C compilers allowed the use of local function definitons

int foo()
{
int bar(int, int);

return bar(1,2);
}

int bar()
int x,
int y
{
return 0;
}

bar is now local to foo(). I think I've got that right. It never caught on
and now static is the universally-approved way of restricting access to a
function.

That's not a local function definition; it's merely a local function
declaration. It's still perfectly legal, just as it always has been,
though it's widely considered to be poor style. (This specific
example would have been illegal before the introduction of prototypes,
but a local "int bar();" would have been legal.)

(There are other problems with the code.)

A local function *definition* would look like this:

int foo(void)
{
int bar(int x, int y)
{
return 0;
}
return bar(1, 2);
}

This has never been legal in standard C. <OT>gcc allows it as an
extension.</OT>

Nested functions make the compiler's job more difficult if it has to
support an inner function referring to an object declared in an outer
function.
 
A

Ancient_Hacker

Hi,

Is there any way, by which we can limit a specific function to be
called
only from a specific function ? I dont know the advantage of this.
Someone
asked this question from me in an interview.

thanks for any help ...

Lotsa ways to do it:

#define f5 if( strcmp( __FUNC__, "f2" ) == 0 ) f5 (); else
printf("cant call f2 from here");

or if your compiler doesnt have __FUNC__, test for __LINE__

or:

#define f5(x) f5 ( __FUNC__, x )
... then have f5 do the strcmp() for the function names its allowed to
be called from.

or:

in global scope have: char f5;

so nobody can call f5, except f2 is:

void f2( void ){ void f5(); // or whatever, now f5 can be called but
only from in here
}
 
C

Chris Dollin

Old said:
f3() can still write:
int f1();

to declare f1, and then call it.

No solution - not even the ones in languages which support interesting
visibility rules - is robust against source editing.
 
G

Guest

CBFalconer said:
Yes it can. The 'static' only prevents visibility outside the
compilation unit.

No, it cannot. f3 is defined before f1 is declared. You can refer to a
static function or variable with an extern declaration if and only if
the a static declaration is already in scope, and you cannot use static
on a function declaration with block scope.
 
C

Christopher Benson-Manica

Old Wolf said:
santosh wrote:
C++ does not support this either.

Right, although he may have been thinking of friends and similar
things, which can do something like OP wanted, albeit for classes and
not functions as was required.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top