473,418 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,418 software developers and data experts.

Runtime type-safety (for linked lists)

Hello all,

I am creating a linked list implementation which will be used in a
number of contexts. As a result, I am defining its value node as type
(void *). I hope to pass something in to its "constructor" so that I
will be able to manipulate my list without the need for constant
casting; some sort of runtime type-safety mechanism.

For example, I want a linked lists of ints. I want to be able to say:

Newguy = ll_new(int); //so that in the future i can say:
Newguy.next.val++;

Or alternatively a list of bools:

Newerguy = ll_new([type]bool) //so that in the future i can say:
Newerguy.next.val = false;

Anyhow, I'm looking for ways to enforce runtime type-safety. Any
thoughts are appreciated, especially since I know for a fact this can
be done (and without unions...).

Dave
Nov 13 '05 #1
2 2413

On Sun, 28 Sep 2003, Dave wrote:

I am creating a linked list implementation which will be used in a
number of contexts. As a result, I am defining its value node as type
(void *). I hope to pass something in to its "constructor" so that I
will be able to manipulate my list without the need for constant
casting; some sort of runtime type-safety mechanism.
Can't be done easily. If you have a variable of type (void *), then
you're going to have to cast it to something else in order to dereference
it. That's just the way C works. But read on.
For example, I want a linked lists of ints. I want to be able to say:

Newguy = ll_new(int); //so that in the future i can say:
Newguy.next.val++;

Well, here are two things I've thought of. You can go the whole hog
and create a big dispatch table inside your linked list class, so
that one can write
struct llnode {
void *val; /* data stored through here */
};
struct my_crazy_llist {
struct llnode *head;
struct llnode *tail;
struct llnode *current; /* for iteration */
[...dispatch stuff...]
};

int ll_add_dispatch(struct llist *who, const char *method,
void *(*how)(void *, va_list));
void *ll_dispatch(struct llist *who, struct llnode *where,
const char *method, ...);

void *int_inc(void *val, va_list ap)
{
++ *(int *)val;
}

void *int_asgn(void *val, va_list ap)
{
*(int *)val = va_arg(ap, int);
return 0;
}

[...]

my_crazy_llist *Newguy = ll_new();
ll_add_dispatch(Newguy, "++", int_inc);
ll_add_dispatch(Newguy, "=", int_asgn);
[...]

ll_dispatch(Newguy, Newguy->current->val, "++");
ll_dispatch(Newguy, Newguy->current->val, "=", 42);

Now, whether you want to go this route is completely up to you
and your asylum warden. A simpler route might be to create
just a few generic routines via #define, and use those for the
commonplace things -- write your own for the complicated things.
E.g.,

#define ASGN(var, type, val) ((*(type *)(var)) = (val))

ASGN(Newguy->current->val, int, 42);

Anyhow, I'm looking for ways to enforce runtime type-safety. Any
thoughts are appreciated, especially since I know for a fact this can
be done (and without unions...).


And how, exactly, *do* you know this can be done? Have you seen
it done before? (Why not just copy that implementation, then?)

My recommendation: Use C++ and templates for this stuff. Don't
mess around with polymorphism in C, because the language simply
isn't designed for that. (Not that hacking around like this isn't
fun; it's just not very productive in the long run.)

-Arthur

Nov 13 '05 #2
da**********@yahoo.com (Dave) wrote in message news:<3e**************************@posting.google. com>...
Hello all,

I am creating a linked list implementation which will be used in a
number of contexts. As a result, I am defining its value node as type
(void *). I hope to pass something in to its "constructor" so that I
will be able to manipulate my list without the need for constant
casting; some sort of runtime type-safety mechanism.

For example, I want a linked lists of ints. I want to be able to say:

Newguy = ll_new(int); //so that in the future i can say:
Newguy.next.val++;

Or alternatively a list of bools:

Newerguy = ll_new([type]bool) //so that in the future i can say:
Newerguy.next.val = false;

You should, if you really need this, listen to Authers advice
and use C++ with templates (in fact, dont "create" anything, just
use the stl to store whatever you want to).

if you are doing it purely for the fun aspect, then a way around
the "dont know what to cast this to" in the code (like the
Newguy = ll_new(int)
above) is to use macros combined with a function that implements
a lookup table based on the type.

----hw.c----
#include <stdio.h>
#include <stdlib.h>

/* the following two arrays must be
kept in synch with one another.
*/
enum the_type_t {
INT,
CHAR,
FLOAT,
DOUBLE,
UNKNOWN
};

char *all_type_strings[] = {
"int",
"char",
"float",
"double",
NULL
};

/* your structure for a single node in a ll */
struct node_t {
void *data;
struct node_t *next;
};

enum the_type_t get_type (char *the_type_string) {
enum the_type_t retvalue = UNKNOWN;
int i;
for (i=0; all_type_strings[i]!=NULL; i++) {
if (strcmp (all_type_strings[i], the_type_string)==0) {
retvalue = i;
break;
}
}
return retvalue;
}

struct node_t *fll_new (enum the_type_t the_type) {
void *data;
struct node_t *node = malloc (sizeof *node);
if (!node) {
return NULL;
}
switch (the_type) {
case INT: data = malloc (sizeof (int)); break;
case CHAR: data = malloc (sizeof (char)); break;
case FLOAT: data = malloc (sizeof (float)); break;
case DOUBLE: data = malloc (sizeof (double)); break;
case UNKNOWN:
default:
data = NULL;
};
node->data = data;

return node;
}
#define ll_new(the_type) fll_new (get_type (#the_type))

int main (void) {
struct node_t *MyData = ll_new (int);

if (!MyData) {
printf ("no mem ?\n");
return EXIT_FAILURE;
}

*(int *)MyData->data = 42;
printf ("data stored = %i\n", *(int *)MyData->data);

/* this can possibly be wrapped into a macro as well */
free (MyData->data);
free (MyData);

return EXIT_SUCCESS;
}

----end of hw.c----

its not too hard to massage the above (rather ugly) code into
a linked list, as the non-intuitive parts of it is already
done. If you know how to implement a normal linked list, then
you could do it.
Anyhow, I'm looking for ways to enforce runtime type-safety. Any
thoughts are appreciated, especially since I know for a fact this can
be done (and without unions...).


I dont think that that (runtime safety) *can* be done properly. but
good luck anyway.
goose,
post a link to the finished goods, will you? i'm interested ;-)
Nov 13 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: H Jansen | last post by:
I try to work out how to use __new__ and metaclass (or __metaclass__) mechanisms in order to change the base class at runtime. I haven't been successful so far, however, even after also reading...
2
by: web1110 | last post by:
Hi y'all, I'm playing with C# again, trying to implement a remoted calculator exercise. If I include: using System.Runtime.Remoting.Channels.Http; I get the error:
3
by: mra | last post by:
I want to cast an object that I have created from a typename to the corresponding type. Can anycone tell me how to do this? Example: //Here, Create the object of type "MyClass" object...
1
by: Samuel R. Neff | last post by:
We just started getting NullReferenceException in one of our applications on our demo server. This is occuring in a .NET Windows Service that is using binary remoting over TCP to talk to another...
3
by: kumar.senthil | last post by:
Hi, I would like to know whether we can create a generic object at runtime using the type obtained using reflection. Type myType = Type.GetType("Namespace.Class"); MyClass<myType> test1 = new...
10
by: Rich | last post by:
I want to replace CSomeObject class with some kind of runtime method that returns type CSomeObject that I can use as cast. How do I specify type of explicit cast at runtime? eg: object...
7
by: John | last post by:
Hi Everyone, I'm having this extremely annoying problem with Internet Explorer 6, giving me an error message saying "unknown runtime error" whenever I try to alter the contents of a <divelement...
3
by: =?Utf-8?B?R3JhaGFt?= | last post by:
I've added 2 tracking services to the wf runtime; one is the standard SqlTrackingService: trackingService = new SqlTrackingService(<trackingConnectionString>); <workflow...
16
by: desktop | last post by:
I have read that using templates makes types know at compile time and using inheritance the types are first decided at runtime. The use of pointers and casts also indicates that the types will...
6
by: rn5a | last post by:
The different Page events in the page life cycle like Page_PreInit, Page_Init, Page_Load etc. - are they different stages of the runtime process? Does a server send back the HTML output of an...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.