Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > An excursion to pseudo-polymorphism

Reply
Thread Tools

An excursion to pseudo-polymorphism

 
 
guillemort@gmail.com
Guest
Posts: n/a
 
      07-18-2006
We have a system of small objects in the lines of

typedef struct {
...
} text_object;

And we have a "object master" that serves as a container for
several of these small objects, in the lines of

typedef struct {
...
text_object *text;
media_object *media;
...
} object_master;

Now, we need a generic/polymorphic way to initialise the small objects
as the initialisation is similar for all of them. I would like to use
inlined functions instead of macros for that, but currently don't see
any natural, clean way for it. A pseudo-implementation with a macro
(ALLOC_OBJ) is provided below.

Any ideas for converting that macro to an inline function?

my_error alloc_text(object_master *om, params* pms)
{
my_errcode err = 0;
text_object *to;
ALLOC_OBJ(om, to, textobj, TEXT_OBJECT_TYPE, pms);
return err;
}

my_error alloc_text(object_master *om, params* pms)
{
my_errcode err = 0;
media_object *mo;
ALLOC_OBJ(om, mo, mediaobj, MEDIA_OBJECT_TYPE, pms);
return err;
}

#define ALLOC_OBJ(objmaster, gen_obj, gen_obj_field, gen_obj_type,
params)
{
my_ASSERT(obj != NULL);
my_ASSERT(params != NULL);

gen_obj = my_malloc(sizeof(*gen_obj));
if (! gen_obj)
return ERR_OOM;

my_memset(gen_obj, 0, sizeof(*gen_obj));

gen_obj->module = my_module_find(params);
if (! gen_obj->module) {
err = ERR_MISSING_MODULE;
goto out_free_gen_obj;
}
if (my_typeof(gen_obj->module) != gen_obj_type) {
err = ERR_WRONG_MODULE;
goto out_free_gen_obj;
}

err = gen_obj->module->mod_init(gen_obj, params);
if (err)
goto out_free_gen_obj;

goto out;

out_free_gen_obj:
my_memset(gen_obj, 0, sizeof(*gen_obj));
my_free(gen_obj);
gen_obj = NULL;

out:
/* especially rigorous w/o a macro */
objmaster->gen_obj_field = gen_obj;
}

 
Reply With Quote
 
 
 
 
Tom St Denis
Guest
Posts: n/a
 
      07-18-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> We have a system of small objects in the lines of
>
> typedef struct {
> ...
> } text_object;



You're trying to emulate C++, the best way is to use a plugin model.
Prepare structures that have the address of functions that do init,
deinit, etc. Then just call through them.

Tom

 
Reply With Quote
 
 
 
 
guillemort@gmail.com
Guest
Posts: n/a
 
      07-18-2006

Tom St Denis wrote:
> (E-Mail Removed) wrote:
> > We have a system of small objects in the lines of
> >
> > typedef struct {
> > ...
> > } text_object;

>
>
> You're trying to emulate C++, the best way is to use a plugin model.
> Prepare structures that have the address of functions that do init,
> deinit, etc. Then just call through them.
>
> Tom


I'm sorry, but this is too vague. I can't see how function pointers can
help in this case. ALLOC_OBJECT() is the problem, as it's generic. No
use of making it a "member function" by a function pointer as there is
nothing object-specifc going on, only identifiers/types change.

Can you perhaps bring an example?

 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      07-18-2006
(E-Mail Removed) wrote:
> I'm sorry, but this is too vague. I can't see how function pointers can
> help in this case. ALLOC_OBJECT() is the problem, as it's generic. No
> use of making it a "member function" by a function pointer as there is
> nothing object-specifc going on, only identifiers/types change.
>
> Can you perhaps bring an example?


http://libtomcrypt.com

That entire library is pluggable. For instance, my HMAC message
authentication code ... er source code [hehehe] doesn't know what hash
you are using. Doesn't know how the hash even works. Just knows it
can call certain functions to handle the message being hashed.

Similarly my Public Key code has no clue how your bignum math is done
[I support three different math libraries, each with their own bignum
data types, init/deinit functions, etc].

etc, etc, etc.

You're just giving up too easily.

Tom

 
Reply With Quote
 
guillemort@gmail.com
Guest
Posts: n/a
 
      07-18-2006

Tom St Denis wrote:
> (E-Mail Removed) wrote:
> > I'm sorry, but this is too vague. I can't see how function pointers can
> > help in this case. ALLOC_OBJECT() is the problem, as it's generic. No
> > use of making it a "member function" by a function pointer as there is
> > nothing object-specifc going on, only identifiers/types change.
> >
> > Can you perhaps bring an example?

>
> http://libtomcrypt.com
>
> That entire library is pluggable. For instance, my HMAC message
> authentication code ... er source code [hehehe] doesn't know what hash
> you are using. Doesn't know how the hash even works. Just knows it
> can call certain functions to handle the message being hashed.
>
> Similarly my Public Key code has no clue how your bignum math is done
> [I support three different math libraries, each with their own bignum
> data types, init/deinit functions, etc].
>
> etc, etc, etc.
>
> You're just giving up too easily.
>
> Tom


This is all elementary run-time polymorphism. This case is a little bit
different and I'm afraid you fail to see the point. Please look at the
initial post and give your own function version of OBJECT_ALLOCATE()
that works both with text_objects and media_objects if you want to help.

 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      07-18-2006
(E-Mail Removed) wrote:
> This is all elementary run-time polymorphism. This case is a little bit
> different and I'm afraid you fail to see the point. Please look at the
> initial post and give your own function version of OBJECT_ALLOCATE()
> that works both with text_objects and media_objects if you want to help.


Are you saying you're adding methods that aren't known at compile time?

Then just do variadic definitions and lookup by name...

func_int_t insert_int = myplugin->lookup(methodname);
insert_int(ID, blah, blah, blah);

I don't care to look at your example because I know that you can
emulate all basic functions of C++ with C structures.

You just have to rethink the approach. It won't always be as nice as
C++ [that's why they invented C++] but you can get the same job done
regardless.

Tom

 
Reply With Quote
 
guillemort@gmail.com
Guest
Posts: n/a
 
      07-19-2006

Tom St Denis wrote:
> I don't care to look at your example because I know that you can
> emulate all basic functions of C++ with C structures.


Tom, why did you answer if you have nothing to say? I'll open another
thread, please don't answer there.

 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      07-19-2006
(E-Mail Removed) schrieb:
> We have a system of small objects in the lines of
>
> typedef struct {
> ...
> } text_object;
>
> And we have a "object master" that serves as a container for
> several of these small objects, in the lines of
>
> typedef struct {
> ...
> text_object *text;
> media_object *media;
> ...
> } object_master;
>
> Now, we need a generic/polymorphic way to initialise the small objects
> as the initialisation is similar for all of them. I would like to use
> inlined functions instead of macros for that, but currently don't see
> any natural, clean way for it. A pseudo-implementation with a macro
> (ALLOC_OBJ) is provided below.


You want templates for this, don't you? In C, you could use a structure,
that contains the common parts:

/* "common" or "base" object */
typedef struct
{
void* module;
} gen_object;

/* specific object */
typedef struct
{
void* module;
void* media_data;
} media_object;

my_error alloc_media(object_master *om, params* pms)
{
my_errcode err = 0;
media_object *mo;
/* ALLOC_OBJ(om, to, textobj, MEDIA_OBJECT_TYPE, pms); */
alloc_obj((gen_object**)&mo, sizeof *mo, MEDIA_OBJECT_TYPE, pms);
om->media = mo;

return err;
}

void alloc_obj(gen_object** obj, size_t size, int type, params* pms)
{
/* no error checking done */
*obj = my_malloc(size);

my_memset(*obj, 0, size);

(*obj)->module = my_module_find(params);

/* ... */
}

--
Thomas
 
Reply With Quote
 
guillemort@gmail.com
Guest
Posts: n/a
 
      07-21-2006

Thomas J. Gritzan wrote:

> You want templates for this, don't you?


Exactly. I should have explicitly pointed that out.

> In C, you could use a structure,
> that contains the common parts:


Well, yes, but it is a little fragile. It seems it is safest to just
stick to the macro. Looks like templates are best emulated with macros,
even though macros are infamous. Like goto that is notoriously
ill-famed, but still useful for try/catch-like error handling. Any
objections?

Thanks for the example, it looks nice and does exactly what I wanted.
However, it seems the macro provides better compile-time safety as no
casts are involved and pointers retain their "identity". I hoped that a
function can be generically used without loosing pointer identity (i.e.
compiler knows the pointer type and hence the pointed-to struct size),
postponing the obvious though in the back of my mind --- it is
impossible. Well, it is impossible and I should not have started this
discussion at all.

 
Reply With Quote
 
Bill Pursell
Guest
Posts: n/a
 
      07-22-2006

(E-Mail Removed) wrote:
> Thomas J. Gritzan wrote:
>
> > You want templates for this, don't you?

>
> Exactly. I should have explicitly pointed that out.
>
> > In C, you could use a structure,
> > that contains the common parts:

>
> Well, yes, but it is a little fragile. It seems it is safest to just
> stick to the macro. Looks like templates are best emulated with macros,
> even though macros are infamous. Like goto that is notoriously
> ill-famed, but still useful for try/catch-like error handling. Any
> objections?
>
> Thanks for the example, it looks nice and does exactly what I wanted.
> However, it seems the macro provides better compile-time safety as no
> casts are involved and pointers retain their "identity". I hoped that a
> function can be generically used without loosing pointer identity (i.e.
> compiler knows the pointer type and hence the pointed-to struct size),
> postponing the obvious though in the back of my mind --- it is
> impossible. Well, it is impossible and I should not have started this
> discussion at all.


NO! You absolutely should have started the discussion. I enjoyed
reading the examples, so even if you didn't get exactly what you
wanted, me (and undoubtedly other thread lurkers) reaped some
benefit.

I was recently playing around with some similar ideas and
had hoped that typedef'ing the void * would generate a
compiler warning, but was unable to coerce any warnings. eg

typedef void * foo;
typedef void * bar;

void f(foo a) {return;}
void g(bar a) {return;}

int main(void)
{
foo a;
bar b;
f(b);
g(a);
return 0;
}

Does anyone know a compiler that will warn here? Better
yet, can I coerce a warning out of gcc?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
a logic excursion Rainer Weikusat Perl Misc 3 03-22-2013 06:01 PM
Re: A CT&P excursion - beat it up! Ron Ford C Programming 10 06-09-2008 07:46 PM
Re: A CT&P excursion - beat it up! gw7rib@aol.com C Programming 3 06-07-2008 10:01 PM



Advertisments