Thread: typedefs and header files

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    2

    typedefs and header files

    Hi all!

    I was wondering if there was a way to defer typedef declaration untill a later time? Now what I'm trying to do is create a general linked list .c & .h file of all the definitions and functions of a list such as listempty, traverselist, createlist etc. However, I want to keep it as general as possible including the data type of the list untill I need it for one of my projects.

    Now I've read a textbook on this subject and it's say's I can declare the datatype just before including the header file of the general list like so:

    typedef MyDataType GeneralDataType;
    #include "general_list.h"

    where: GeneralDataType is undefined and part of a structure in general_list.h and MyDataType is a clearly defined datatype such as char, int or some other structure.

    The problem I'm having is that general_list.c complains that I haven't defined what GeneralDataType is even though I have defined it in the header file of a main program.

    Is there a work around or preprocessor command I'm missing? Any help would be greatly appreciated.

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    That is because general_list.c and your main program source file are compiled independtly of each other. As for a work around I can't think of any off the top of my head but I'm sure there is one.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >>[b]...general_list.c complains that I haven't defined what GeneralDataType is...[b]
    >>...I have defined it in the header file...
    Did you #include the header within general_list.c?

    >>Is there a work around...
    Get what you have working first. Once you understand how this method works, we can talk about other methods that have different advantages/disadvantages.

    gg

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Is there a work around or preprocessor command I'm missing?

    you could put the .c code into .h file to simplify things and just use a define:

    #define GeneralDataType struct customer
    #include "general_list.h"
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Well sounds like a job for void

    Code:
    struct node {
        void *data;
        struct node *next;
    };
    
    struct node *insertAtHead ( struct node *head, void *data ) {
        struct node *new = malloc( sizeof *new );
        new->data = data;
        new->next = head;
        return new;
    }
    Then you can do things like
    Code:
    struct node *list1 = NULL;
    struct node *list2 = NULL;
    list1 = insertAtHead( list1, &myint );
    list2 = insertAtHead( list2, &mych );
    But you do need to allocate space for your data in this example, though no doubt a more sophisticated implementation could take care of that.

    The list implementation only ever has to deal with a void* pointer to the thing you want to store in the list, so it could be anything you want when you use the list.

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    2
    Quote Originally Posted by Thantos
    That is because general_list.c and your main program source file are compiled independtly of each other.
    Ah I see. I always thought that if you included the necessary file headers into your program then they would be compiled succinctly but I guess it's too much to ask c to compile first and ask questions later about the datatype.

    Quote Originally Posted by Sebastiani
    you could put the .c code into .h file to simplify things and just use a define:
    No,I don't want to do that since I want to modularize & encapsulate my code so that if others want to use my code, I can just give them the object and header file.

    Quote Originally Posted by Salem
    Well sounds like a job for void
    I was thinking of implementing it this way and it seems I have no choice given the fact that I or anyone else can't predict what future datatypes will be stored in this general list. The only problem I have with this is the example you gave of the list being allowed to store any data type in the list which is kind of like a mixed bag of goodies waiting to be spilled all over the table. Segmentation faults anyone? But this is generally acceptable I guess since this is c and c generally assumes the programmers know what their doing.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    It seems to me what you're trying to do is implement C++ templates in C

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I guess it's too much to ask c to compile first and ask questions later about the datatype.
    Yes, it is. If you want dynamic typing, might I suggest Perl or Python?

    >I or anyone else can't predict what future datatypes will be stored in this general list.
    That's why they call it a general list.

    >Segmentation faults anyone?
    It's not nearly the issue you make it out to be. I can only think of a few times where there was any question what type of content I had in a data structure. And the question was answered with a quick check before I tried to do anything stupid. Pointers to void generally don't cause a problem unless the user programmer is incredibly stupid, very inexperienced, or has malicious intent.

    >since this is c and c generally assumes the programmers know what their doing.
    So does C++, whose template feature is what you seem to be in need of.
    My best code is written with the delete key.

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    One typical solution is to require that the first member of a struct added to a list is the control data struct. Here is an example from a WinAPI linked list implementation:
    Code:
    typedef struct _PROGRAM_ITEM {
        SLIST_ENTRY ItemEntry; /* Control data is first member of struct. */
        ULONG Signature;  /* Any user data follows. */
    } PROGRAM_ITEM, *PPROGRAM_ITEM;
    
    int main(void)
    {
        ULONG Count;
        PSLIST_ENTRY FirstEntry, ListEntry;
        SLIST_HEADER ListHead;
        PPROGRAM_ITEM ProgramItem;
    
        // Initialize the list header.
        InitializeSListHead(&ListHead);
    
        // Insert 10 items into the list.
        for( Count = 1; Count <= 10; Count += 1 )
        {
            ProgramItem = (PPROGRAM_ITEM)malloc(sizeof(*ProgramItem)); /* User takes care of memory allocation. */
            ProgramItem->Signature = Count;
            FirstEntry = InterlockedPushEntrySList(&ListHead, 
                           &ProgramItem->ItemEntry); /* Your list functions simply manipulate the control data, you don't know the actual size of the struct. */
        }
    
        // Remove 10 items from the list.
        for( Count = 10; Count >= 1; Count -= 1 )
        {
            ProgramItem = (PPROGRAM_ITEM) InterlockedPopEntrySList(&ListHead);
            printf("Signature is %u\n", ProgramItem->Signature);
            free(ProgramItem);
        }
    
        ...
    Of course if you need the actual size of the data struct, for sorting or other reasons, you can pass that in too.

    >> So does C++, whose template feature is what you seem to be in need of. <<

    It seems csprite could get crude template functionality by including the code, as suggested previously. Another option is to use a project level define. Neither of these options allow different data types to be used in the same file.
    Last edited by anonytmouse; 12-05-2004 at 12:37 AM. Reason: The sun was bright and I sat in the shade of a large tree.

  10. #10
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    void main( )
    My eyes my eyes!

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Yeah I just handed out some candy for that one.

    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Well in all fairness anonytmouse was just showing us how MS does it which we all know is crap code

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >anonytmouse
    >Join Date: Dec 2002
    >Posts: 1,175
    >
    >void main( )
    Aroo? My math may not be the best, but you should know better. Let the beatings begin!
    My best code is written with the delete key.

  14. #14
    ---
    Join Date
    May 2004
    Posts
    1,379
    *sand_man beats anonytmouse with a whacking stick

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why do we use the header file in C
    By bhanubaba in forum C Programming
    Replies: 4
    Last Post: 09-10-2007, 09:35 AM
  2. Using typedefs within classes.
    By indigo0086 in forum C++ Programming
    Replies: 4
    Last Post: 07-12-2006, 10:17 AM
  3. header and source files
    By gtriarhos in forum C Programming
    Replies: 3
    Last Post: 10-02-2005, 03:16 AM
  4. how to use typedefs with structs?
    By Yourhighness in forum C Programming
    Replies: 9
    Last Post: 06-03-2003, 04:43 AM
  5. Using TypeDefs
    By peking1983 in forum C Programming
    Replies: 2
    Last Post: 03-14-2003, 01:26 AM