Thread: struct array's inheritance

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    7

    struct array's inheritance

    Ok, so I know inheritance isn't actually implemented in C, but I've used one of the very common workarounds, and I'd like to know how to pass the "inherited" structure to a function (which is expecting an array of the base structure). The problem is, I have an array of the parent structure, and want to pass an equivalent array of the base structure (see below, I'm also getting a "suspicious pointer conversion warning"). Is this even possible, or do I have to create an interim function that will iterate through each base member of the parent structure and put it in a new array? (v. easy but inelegant). This is the best I've got so far:

    Code:
    typedef struct io {
    	int p_loc;
    } io_t;
    
    typedef struct led {
    	io_t io;
    	int state;
    } led_t;
    
    void io_set_locs(int loc[], io_t (*I)[]) {
    	int i=0;
    	for (; i<8; i++) I[i]->p_loc = loc[i];
    }
    
    void main(void) {
    	led_t L[8];
    	int loc_L[] = {0x110,0x120,0x140,0x180,0x040,0x080,0x104,0x108};
    
    	io_set_locs(loc_L, &L->io);
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    There's no good way that I can think of without building an auxiliary array first.

    BTW: Do you intend I to be a pointer to an array (the way you have it declared in the function header) or an array of pointers (the way you're using it in the function itself)?

  3. #3
    Registered User
    Join Date
    Jun 2008
    Posts
    7
    thanks for looking at it, tabstop. I read something somewhere about casting the pointer up to the parent, because it's the first definition in the child, but I'm not used to pointers yet (coming from minimal C++ background). The header was correct, so changed the others, your explanation of the type of pointer was helpful, as I'd changed from the correct version earlier because someone (in another thread) said it would be easier. The intermediary function didn't work, so have ended up just implementing the assigning for loop inside the structures' "constructor", meaning I have several copies of the same loop through my source files.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    How about just initializing the struct itself when you create the variable?

    Code:
    typedef struct io {
    	int p_loc;
    } io_t;
    
    typedef struct led {
    	io_t io;
    	int state;
    } led_t;
    
    int main(void) {
      led_t L[8] = { { { 0x110 } }, 
    		 { { 0x120 } }, 
    		 { { 0x140 } },
    		 { { 0x180 } },
    		 { { 0x040 } },
    		 { { 0x080 } },
    		 { { 0x104 } },
    		 { { 0x108 } } };
    
      return 0;
    }
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Jun 2008
    Posts
    7
    because I now have it all abstracted enough that I no longer need to know about the structure of the led class, but I do need to send the port locations of the LEDs as arguments to the function that deals with it all (the only thing likely to change between different instances of the same hardware is the port location) I'm now trying to learn about dynamic memory allocation, so the LED array size can be set by the size of the port allocation array argument. i.e. the equivalent functionality of the uncompilable code snippet:

    Code:
    int my_function(int loc[]) {
      int n=sizeof loc / sizeof loc[0];
      led_t L[n];
      ...
      return 0;
    }

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Pass the size of the array as well, and then malloc() whatever you need. Don't forget to free() the memory later on.

  7. #7
    Registered User
    Join Date
    Jun 2008
    Posts
    7
    thanks, I'm looking up how to use malloc() etc. at the moment. My (current) task is to design a library of functions that a main() written by someone else could call, knowing the function, but not (necessarily) it's implementation. As such, asking them to supply the size of the array is inconvenient at best, as the information provided by the extra argument is inherently supplied as part of the other argument. Are you sure I have to pass the size as an argument? or can I set n before dealing with malloc().

  8. #8
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by emorrp1 View Post
    As such, asking them to supply the size of the array is inconvenient at best, as the information provided by the extra argument is inherently supplied as part of the other argument.
    Um, no it's not. When you pass an array to a function, you're not passing the array. You're passing a pointer to the first element of the array, and therefore losing any and all array-specific information about said array.

    Quote Originally Posted by emorrp1 View Post
    Are you sure I have to pass the size as an argument?
    Yes.

    Quote Originally Posted by emorrp1 View Post
    or can I set n before dealing with malloc().
    And how do you propose to do that?

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You have to find a way then to calculate the size of the array. But there is not way to do this in C, you don't have an array.length() method or something, because an array is C is actually a pointer pointing to the first element of the "array".

    You could make your own array struct like:
    Code:
    typedef struct array {
       type_t *a;
       int size;
    } array;
    then you can pass the array in functions. Still the size is needed to be calculated. You can make your own function to do this. Like:
    Code:
    array * create_array(int size)
    {
        array * ar_ptr;
        ar_ptr = (array *)malloc(size * sizeof(array));
        if (type ar_ptr != NULL)
           ar_ptr->size = size;
        else
            printf("Error!\n");
           // or anything else for errors
        return ar_ptr;
    }
    
    void destroy_array(array *ar_ptr)
    {
       free(ar_ptr);
    }
    So everyone can use an array which has its size. You can provide more functions for the array type.
    All the other functions can have only a pointer to array passed to them and have all the necessary information.

    So the values would be accessed like array->a[i], and the size array->size. Of course anyone that uses your library would know that he must use your array type and the functions you made to create, destroy, re-size or anything else for it.
    Last edited by C_ntua; 06-27-2008 at 05:59 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting from C to C++
    By Taka in forum C++ Programming
    Replies: 5
    Last Post: 04-08-2009, 02:16 AM
  2. Looking for constructive criticism
    By wd_kendrick in forum C Programming
    Replies: 16
    Last Post: 05-28-2008, 09:42 AM
  3. Concatenating in linked list
    By drater in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 11:10 PM
  4. Save data from two struct arrays in one .dat file
    By IndioDoido in forum C Programming
    Replies: 5
    Last Post: 03-27-2008, 03:50 PM
  5. Inheritance from C struct
    By WDT in forum Networking/Device Communication
    Replies: 6
    Last Post: 11-24-2007, 04:41 PM