Thread: dynamicly adding data members to structs

  1. #1
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72

    dynamicly adding data members to structs

    C only please, no C++.

    My eventual goal is to be able to translate Python into C to be compiled by the C compiler. As I see it there's two steps, create a dynamic typing library for C, and create the actual translator. I'm already working on a basic dynamic type and the results so far are good.

    Here's the problem, in python the data in classes are created dynamicly, there's no way to predefine them. Here's some example Python code:

    Code:
    #create an empty class named "person"
    class person:
        pass
    #create a "person" instance
    some_name = person()
    #assign data members to "some_name"
    some_name.name = "Homer Simpson"
    some_name.age = 39 #this is a guess, I'm not sure how old he is
    some_name.gender = "M"
    #print the newly assigned data
    print some_name.name, some_name.age, some_name.gender
    Homer Simpson 39 M
    Python handles those dynamic class members (and all variables) with string-based hash tables. I wish to accomplish the same thing in C without the hash tables if possible. If I have to use hash tables could I use memory addresses instead of strings? Integer comparisons are much faster than string comparisons. Any ideas on how I can do this without hash tables?

    Thanks in advance.
    Last edited by ITAmember; 05-31-2009 at 06:00 PM. Reason: typo

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    I if have to use hash tables could I use memory addresses instead of strings? Integer comparisons are much faster than string comparisons.
    Huh? If you're thinking what I think you're thinking, then no. You should key on the string, not the address where the string is located. If you did key on the address, how am I supposed to do a lookup into this hashtable? I have the string I want, which may or may not exist at the same address as the string you have in the table. Key on the string. Look into hashes if you absolutely have to, but only after profiling says the hash table is a bottleneck. It's a hash table. If you're Doing It Right™, then it's a single comparision. Maybe two or three in the worst case.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  3. #3
    Registered User Homer_Simpson's Avatar
    Join Date
    May 2009
    Posts
    22
    Quote Originally Posted by ITAmember View Post
    I wish to accomplish the same thing in C without the hash tables if possible. I if have to use hash tables could I use memory addresses instead of strings? Integer comparisons are much faster than string comparisons. Any ideas on how I can do this without hash tables?
    Beats me.

  4. #4
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    Quote Originally Posted by Cactus_Hugger View Post
    Huh? If you're thinking what I think you're thinking, then no. You should key on the string, not the address where the string is located. If you did key on the address, how am I supposed to do a lookup into this hashtable? I have the string I want, which may or may not exist at the same address as the string you have in the table. Key on the string. Look into hashes if you absolutely have to, but only after profiling says the hash table is a bottleneck. It's a hash table. If you're Doing It Right™, then it's a single comparision. Maybe two or three in the worst case.
    Hashtable is not the right word if I do use the memory addresses. Let's say my struct has variables a, b, and c. My struct has a list of pointers to the data members, a, b, and c to store the memory addresses. Let's say I want to add variable d to the struct, I would go through the list of variable pointers and compare the address of d to the addresses of a, b, and c. If I got a match then the variable d is already in the struct and I would throw an error, if i don't get a match then I add d the address of d to the list. I would then follow a similar protocall for all operations related to these variables.

    What I really want is a way to do this without hashtables. (or address lists)

    Thanks for the speedy reply though.
    Last edited by ITAmember; 05-31-2009 at 06:01 PM. Reason: typo

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    > I would go through the list of variable pointers and compare the address of d to the addresses of a, b, and c.
    That's not going to tell you much at all. You still want to compare the values of at the addresses. i.e. *a == *d

    If you don't want to use a hash table, then consider a binary tree of people. Or even just a sorted list of people.

    Your explanations are very blurry, considering you basically explained (not legal C):
    Code:
    struct x
    {
       int a, b, c;
       int * a, * b, * c;
    }
    And you want to add 'd' to the struct.

    You mean, given a list of people how do I find out if member x in any of the people has a value of d?

    I would also be concerned, that there have been a few "Simpsons" questions posted here, and there is a new member called "Homer_Simpson" that has been replying to them. So you're probably being watched
    Last edited by zacs7; 05-31-2009 at 06:09 PM.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    How about:
    Code:
    struct dyn_obj {
          void **array;  /* array of addresses */
          char *names[]; /* parallel array of variable descriptors */
          int *types; /*pointer to parallel array of variable types */
          int length; /* length of array
    };
    Last edited by MK27; 05-31-2009 at 06:23 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    I've got the dynamic object thingy down, I want to be able to add objects to a struct without predeclaring them. I'm not sure if that's what the code is as it looks like a dynamic object type, not a way to implement a dynamic struct.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ITAmember View Post
    I've got the dynamic object thingy down, I want to be able to add objects to a struct without predeclaring them. I'm not sure if that's what the code is as it looks like a dynamic object type, not a way to implement a dynamic struct.
    Just an idea. Whatever you want to call it, you could use it to dynamically add pointers to a struct, my impression was that was the goal, there would have to be a function like:
    Code:
    int (struct dyn_obj *ptr, void *data_addr, char *name, int type); /* returns success or error */
    Using some realloc to expand the struct to hold new members whenever.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    I kind of see what you mean now, I've been giving it some thought and this is what I came up with.

    Here's my dynamic object definition code:

    Code:
    typedef struct
    {
        int memory_address; /* stores the memory address of the current object, accessed/mutated via assembly */
        int type; /* stores the type of the object, this may be removed as it might not be needed */
    } object;
    The memory_address value stores the address of some object type defined by a struct. All those object types need to have data members and methods (function pointers) added to them at runtime, without predeclaring them. Here's an example:

    Code:
    typedef struct
    {
        linked_list_of_object_addresses data;
    } dynamic_struct;
    This will be the base of all objects, built in types will have the linked_list_of_object_addresses filled in with some data members and methods before the program starts. Here's a function that would add a data member if it's not already in the list:

    Code:
     int append(object &a, object &b) /* a is the object to append to, b is the object to append */
    {
        for(int i = 0; i < len(*a); i++) /* len returns the length of linked_list_of_object_addresses */
        {
            if(b = (*a)[i])
            {
                return 0;
            }
        (*a).linked_list_of_object_addresses.add(b);
        return 1;
    }
    I know it's pseudocode but the idea would work right?
    Last edited by ITAmember; 06-01-2009 at 02:23 PM.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ITAmember View Post
    I know it's pseudocode but the idea would work right?
    Good question. I should admit I don't know python and I've never done anything like this. I would have separate lists for "data members" and "methods", esp. considering you might want two different styles of node for them.

    Not sure why you're worried about adding data members that already exist; if this has to do with your own pre-runtime set-up (ie, of built in classes and methods), I don't think this method of keeping your tish sorted inspires confidence If it is to prevent a user from doing the same, I think you should let them rather than incorporate (performance reducing) error checks to handle bad programming.

    On the topic of optimization, a lil' note:
    Code:
    for(int i = 0; i < len(*a); i++)
    Be aware that "len(*a)" will get called EVERY time the loop iterates, not just once. So, since AFAICT that value does not change during the loop, call it once and put it into a variable:
    Code:
    int x = len(*a); 
    for(int i = 0; i < x; i++)
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    What I really want is a way to do this without hashtables.
    Why do you want to avoid hash tables? Your method that you have outlined is way slower than a hash table implementation.

  12. #12
    Registered User ITAmember's Avatar
    Join Date
    Mar 2009
    Location
    Nebraska
    Posts
    72
    Quote Originally Posted by MK27 View Post
    Good question. I should admit I don't know python and I've never done anything like this. I would have separate lists for "data members" and "methods", esp. considering you might want two different styles of node for them.
    One problem, take a look at this Python code:

    Code:
    # define an empty class
    class a:
        pass
    
    # define a function
    def b(c):
        return c * c
    
    # create an instance of "a" named "d"
    d = a()
    
    # add the function "b" to "d" as "e" as a method
    d.e = b
    
    # view the method
    print d.e
    
    # call the function
    print d.e(5)
    
    # output:
    
    <function b at 0x00B3AF70>
    25
    The functions and data values are all the same, the "object" type would support function pointers.

    Not sure why you're worried about adding data members that already exist; if this has to do with your own pre-runtime set-up (ie, of built in classes and methods), I don't think this method of keeping your tish sorted inspires confidence If it is to prevent a user from doing the same, I think you should let them rather than incorporate (performance reducing) error checks to handle bad programming.
    Instead of returning an error it should modify the variable, thanks for pointing that out. As far as the error checking it's going to be slow because I'm going to have to do a huge amount. (the downside of dynamic typing) It is required however as descriptive error messages are much better than segmentation faults. I was thinking I would write two versions of the compiler, one would generate error checking code and one would not.

    On the topic of optimization, a lil' note:
    Code:
    for(int i = 0; i < len(*a); i++)
    Be aware that "len(*a)" will get called EVERY time the loop iterates, not just once. So, since AFAICT that value does not change during the loop, call it once and put it into a variable:
    Code:
    int x = len(*a); 
    for(int i = 0; i < x; i++)
    That completely slipped my mind, thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  2. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  3. HUGE fps jump
    By DavidP in forum Game Programming
    Replies: 23
    Last Post: 07-01-2004, 10:36 AM
  4. Accessing private data members
    By maloy in forum C++ Programming
    Replies: 11
    Last Post: 10-04-2002, 02:48 PM
  5. static and non-static data members
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 06-16-2002, 10:06 AM