simulating private member functions--static linkage

B

Bill Pursell

I've been thinking of doing things like the following:

[tmp]$ cat foo.h

struct foo{
int a;
void (*init)(struct foo *, int);
};

void new_foo(struct foo *self);

[tmp]$ cat foo.c
#include "foo.h"

static void init(struct foo *self, int a)
{
self->a = a;
}


void new_foo(struct foo *self)
{
self->init=init;
}

[tmp]$ cat a.c

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

int main()
{
struct foo f;
new_foo(&f);
f.init(&f,10);
/* can't call init from foo.c directly, because it was declared
static */
}

Basically, I'm providing what in other languages might be called
(pseudo)-private member function to foo. I don't understand the static
linkage mechanism well enough to know if this is a bad idea. It seems
to work well, but I've only used it in very small toy test cases. Are
there any reasons to avoid this type of construction?
 
J

jefong

Bill said:
I've been thinking of doing things like the following:

[tmp]$ cat foo.h

struct foo{
int a;
void (*init)(struct foo *, int);
};

void new_foo(struct foo *self);
// I think you should declare the function's type in here.
void init(struct foo *self, int a)
[tmp]$ cat foo.c
#include "foo.h"

static void init(struct foo *self, int a)
{
self->a = a;
}


void new_foo(struct foo *self)
{
self->init=init;
}

[tmp]$ cat a.c

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

int main()
{
struct foo f;
new_foo(&f);
f.init(&f,10);
/* can't call init from foo.c directly, because it was declared
static */
}

Basically, I'm providing what in other languages might be called
(pseudo)-private member function to foo. I don't understand the static
linkage mechanism well enough to know if this is a bad idea. It seems
to work well, but I've only used it in very small toy test cases. Are
there any reasons to avoid this type of construction?
 
5

50h d'essai

Hello Bill Pursell, All !
I've been thinking of doing things like the following:

[tmp]$ cat foo.h

struct foo{
int a;
void (*init)(struct foo *, int);
};

void new_foo(struct foo *self);

[tmp]$ cat foo.c
#include "foo.h"

static void init(struct foo *self, int a)
{
self->a = a;
}

[tmp]$ cat a.c

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

int main()
{
struct foo f;
new_foo(&f);
f.init(&f,10);
/* can't call init from foo.c directly, because it was declared
static */
}

can't call init from a.c maybe ?

Basically, I'm providing what in other languages might be called
(pseudo)-private member function to foo. I don't understand the static
linkage mechanism well enough to know if this is a bad idea. It seems
to work well, but I've only used it in very small toy test cases. Are
there any reasons to avoid this type of construction?

In C AFAIK function is considered as a global object. This avoids to
place keyword extern every time. static keyword limits the range of
visibility of that function to source file within it is declared. Hope
it helps.
 
J

jefong

you are only declare a function type pointer.so it need to be assigned,
then you can call it.
 
M

Michael Wojcik

I've been thinking of doing things like the following:

[snip code that assigns a static function's address to a function
pointer in a structure, then calls the function through that pointer]

Basically, I'm providing what in other languages might be called
(pseudo)-private member function to foo. I don't understand the static
linkage mechanism well enough to know if this is a bad idea. It seems
to work well, but I've only used it in very small toy test cases. Are
there any reasons to avoid this type of construction?

It's safe; static linkage limits the visibility of a function, but
you're allowed to call that function from a scope where it isn't
visible via a function pointer. This sort of construct is commonly
used to implement polymorphism in C (that is, it's commonly used in
programs where the author wants to implement polymorphism).

I think it's a useful technique. There are many possible variations;
for example, some people prefer to write factory functions that
allocate the structure for the caller. But the short answer is that
what you're doing is fine.

(Of course, there are always reasons to avoid any construction in
some circumstances; you wouldn't do this for every single function
in your program. Used judiciously it's quite useful.)
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top