previous declaration of Table was here / conflicting types for

Discussion in 'C Programming' started by Michael.Z, May 3, 2008.

  1. Michael.Z

    Michael.Z Guest

    Anyone who can help:

    Given a Table.h file I am writing a Table.c file.
    I keep getting the compile error:

    previous declaration of Table was here / conflicting types for


    I think the problem was the result of two pieces of code.
    First: typedef struct Table; /* in Table.c*/
    Second: struct Table { /*struct definition */ } *Table; /* in
    Table.h */

    How can I solve the problems?



    Here are the two files


    /* * * * * * * * * * * * * * * * * * * * * * *
    Header file:
    * * * * * * * * * * * * * * * * * * * * * * */


    #ifndef TABLE_H
    #define TABLE_H


    #include "bool.h"

    typedef void * Table ;
    typedef void * DataT ;

    typedef struct {
    // unsigned successful ; double unsuccessful ;
    unsigned successfulNumerator , successfulDenominator ;
    unsigned unsuccessfulNumerator , unsuccessfulDenominator ;
    } Perform ;

    Table
    makeTable ( int sizeTable , unsigned sizeData , int (*diff)() ,
    unsigned (*hash)() , void * (*copy)() , void (*free)() ) ;


    #endif



    /* * * * * * * * * * * * * * * * * * * * * * *
    Table.c
    * * * * * * * * * * * * * * * * * * * * * * */

    #include "Table.h"


    typedef struct Table{
    int sizeTable;
    unsigned sizeData;
    int (*diff)();
    unsigned (*hash)();
    void *(*copy)();
    void (*free)();
    } * Table;

    Table
    makeTable ( int sizeTable , unsigned sizeData , int (*diff)() ,
    unsigned (*hash)() , void * (*copy)() , void (*free)() ) {
    }
    Michael.Z, May 3, 2008
    #1
    1. Advertising

  2. Michael.Z

    Flash Gordon Guest

    Michael.Z wrote, On 03/05/08 08:22:
    > Anyone who can help:
    >
    > Given a Table.h file I am writing a Table.c file.
    > I keep getting the compile error:
    >
    > previous declaration of Table was here / conflicting types for
    >
    >
    > I think the problem was the result of two pieces of code.
    > First: typedef struct Table; /* in Table.c*/


    This says that Table is a struct.

    > Second: struct Table { /*struct definition */ } *Table; /* in
    > Table.h */


    This says it is a pointer to a struct, that is what the * means.

    > How can I solve the problems?


    By not providing different definitions.

    > Here are the two files


    <snip>

    > typedef void * Table ;


    This is not what you said you had and is defining table as yet another type.

    <snip>

    > typedef struct Table{
    > int sizeTable;
    > unsigned sizeData;
    > int (*diff)();
    > unsigned (*hash)();
    > void *(*copy)();
    > void (*free)();
    > } * Table;



    This is what you said. However pointers to void and pointers to structs
    are different things for the simple reason that void and struct are
    different.

    Also hiding pointers behind a typedef is generally considered a bad thing.
    --
    Flash Gordon
    Flash Gordon, May 3, 2008
    #2
    1. Advertising

  3. Michael.Z

    ade ishs Guest

    Michael.Z wrote:
    > Anyone who can help:
    >
    > Given a Table.h file I am writing a Table.c file.
    > I keep getting the compile error:
    >
    > previous declaration of Table was here / conflicting types for


    > #ifndef TABLE_H
    > #define TABLE_H
    >
    > #include "bool.h"
    >
    > typedef void * Table ;


    You have it here, ...

    [snip]

    > /* * * * * * * * * * * * * * * * * * * * * * *
    > Table.c
    > * * * * * * * * * * * * * * * * * * * * * * */
    >
    > #include "Table.h"
    >
    >
    > typedef struct Table{
    > int sizeTable;
    > unsigned sizeData;
    > int (*diff)();
    > unsigned (*hash)();
    > void *(*copy)();
    > void (*free)();
    > } * Table;


    And you also have it here.

    In Table.h, you make Table a typedef of void *, and in Table.c, you make
    Table a typedef of struct Table { ... } *.
    ade ishs, May 3, 2008
    #3
  4. Michael.Z

    Michael.Z Guest

    Re: previous declaration of Table was here / conflicting types for

    Hi Flash Gordon:

    Thanks for your reply.
    The Table.c was required to be implemented as generic type. If I am
    right, Table is declared as void * in header file, the reason is that,
    when used later on, it can be casted to any other type of pointers.

    The implementation of Table in Table.c was defined as pointer to
    struct Table, because I need to implement the members of Table.

    My professor told us, void * in header indicates a generic type.
    He has some sample codes where List was typedef'd void pointer but the
    definition was struct List Pointer:

    /* Header file List.h*/
    #ifndef LIST_H
    #define LIST_H

    #include "bool.h"

    typedef void * List ;
    typedef void * DataL ;
    typedef void * ListIt ;

    List makeList ( int , void * (*copy)() , void (*free)() ) ;
    void freeList ( List ) ;
    void clearList ( List ) ;

    boolean accessList ( List , DataL , int ) ;
    int lengthList ( List ) ;

    boolean accessHead ( List , DataL ) ;
    boolean insertHead ( List , DataL ) ;
    boolean deleteHead ( List , DataL ) ;

    /* not all the header file is copied here*/









    /* List.c */

    #include "bool.h"
    #include <stdio.h>
    #include <stdlib.h>

    #ifndef DATA
    #define DATA
    typedef void * Data ;
    #endif

    typedef struct ListNode {
    struct ListNode * next ; /* reference to following ListNode */
    struct ListNode * previous ; /* reference to preceding ListNode */
    Data dptr ;
    } ListNode ;

    typedef struct List {
    ListNode * head ; /* Head end of List */
    ListNode * tail ; /* Tail end of List */
    int _lengthList ; /* number of items within List */
    int _sizeData ; /* byte size of data to be stored */
    void (*_freeData)( ) ; /* returns data item to heap */
    void * (*_copyData)( ) ; /* copies data item to another */
    } * List ;


    Regards
    Michael




    On May 3, 2:32 am, Flash Gordon <> wrote:
    > Michael.Z wrote, On 03/05/08 08:22:
    >
    > > Anyone who can help:

    >
    > > Given a Table.h file I am writing a Table.c file.
    > > I keep getting the compile error:

    >
    > > previous declaration of Table was here / conflicting types for

    >
    > > I think the problem was the result of two pieces of code.
    > > First:typedefstruct Table; /* in Table.c*/

    >
    > This says that Table is a struct.
    >
    > > Second: struct Table { /*struct definition */ } *Table; /* in
    > > Table.h */

    >
    > This says it is a pointer to a struct, that is what the * means.
    >
    > > How can I solve the problems?

    >
    > By not providing different definitions.
    >
    > > Here are the two files

    >
    > <snip>
    >
    > >typedefvoid * Table ;

    >
    > This is not what you said you had and is defining table as yet another type.
    >
    > <snip>
    >
    > >typedefstruct Table{
    > > int sizeTable;
    > > unsigned sizeData;
    > > int (*diff)();
    > > unsigned (*hash)();
    > > void *(*copy)();
    > > void (*free)();
    > > } * Table;

    >
    > This is what you said. However pointers to void and pointers to structs
    > are different things for the simple reason that void and struct are
    > different.
    >
    > Also hiding pointers behind atypedefis generally considered a bad thing.
    > --
    > Flash Gordon
    Michael.Z, May 6, 2008
    #4
  5. Re: previous declaration of Table was here / conflicting types for

    On 6 May, 03:33, "Michael.Z" <> wrote:
    > Hi Flash Gordon:


    > The Table.c was required to be implemented as generic type.


    I'm not sure what a "generic type" is and I have been programming
    for quite a while.

    > If I am
    > right, Table is declared as void * in header file, the reason is that,
    > when used later on, it can be casted to any other type of pointers.


    It may be you trying to hide implementation details from users
    of your code. The outside world uses a void* and your
    code (the library) casts it to the right type before use.
    This is good. The internal data structure can change
    without causing a recompile of the user code.

    /* pippo.h */
    typedef void* Table_handle;
    Table_handle create();
    void befunge (Table_handle);

    /* pippo.c */
    void befunge (Table_handle handle)
    {
    Table* table = (Table*)handle;
    ...
    }

    /* user.c */
    int main (void)
    {
    Table_handle* my_table;
    my_table = create();
    befunge(my_table);
    return 0;
    }

    The point is I *don't* try and have two differing
    definitions of Table.


    > The implementation of Table in Table.c was defined as pointer to
    > struct Table, because I need to implement the members of Table.
    >
    > My professor told us, void * in header indicates a generic type.
    > He has some sample codes where List was typedef'd void pointer but the
    > definition was struct List Pointer:


    so he had two different types didn't he?


    > /* Header file List.h*/
    > #ifndef LIST_H
    > #define LIST_H
    >
    > #include "bool.h"
    >
    >         typedef void * List ;
    >         typedef void * DataL ;
    >         typedef void * ListIt ;
    >
    >         List makeList ( int , void * (*copy)() , void (*free)() ) ;
    >         void freeList ( List ) ;
    >         void clearList ( List ) ;
    >
    >         boolean accessList ( List , DataL , int ) ;
    >         int lengthList ( List ) ;
    >
    >         boolean accessHead ( List , DataL ) ;
    >         boolean insertHead ( List , DataL ) ;
    >         boolean deleteHead ( List , DataL ) ;
    >
    >      /* not all the header file is copied here*/
    >
    > /* List.c */
    >
    > #include "bool.h"
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > #ifndef DATA
    > #define DATA
    > typedef void * Data ;
    > #endif
    >
    > typedef struct ListNode {
    >         struct ListNode * next ;        /* reference to following ListNode */
    >         struct ListNode * previous ;    /* reference to preceding ListNode */
    >         Data dptr ;
    >
    > } ListNode ;
    >
    > typedef struct List {
    >         ListNode * head ;               /* Head end of List             */
    >         ListNode * tail ;               /* Tail end of List             */
    >         int _lengthList ;               /* number of items within List  */
    >         int _sizeData ;                 /* byte size of data to be stored */
    >         void (*_freeData)( ) ;          /* returns data item to heap    */
    >         void * (*_copyData)( ) ;        /* copies data item to another  */
    >
    > } * List ;


    arg!!!

    don't top post. Please put your reply after the text you are
    replying to.


    > On May 3, 2:32 am, Flash Gordon <> wrote:
    >
    >
    >
    > > Michael.Z wrote, On 03/05/08 08:22:

    >
    > > > Anyone who can help:

    >
    > > > Given a Table.h file I am writing a Table.c file.
    > > > I keep getting the compile error:

    >
    > > > previous declaration of Table was here /  conflicting types for

    >
    > > > I think the problem was the result of two pieces of code.
    > > > First:typedefstruct Table;  /* in Table.c*/

    >
    > > This says that Table is a struct.

    >
    > > > Second: struct Table { /*struct definition */ }  *Table;  /* in
    > > > Table.h */

    >
    > > This says it is a pointer to a struct, that is what the * means.

    >
    > > > How can I solve the problems?

    >
    > > By not providing different definitions.

    >
    > > > Here are the two files

    >
    > > <snip>

    >
    > > >typedefvoid * Table ;

    >
    > > This is not what you said you had and is defining table as yet another type.

    >
    > > <snip>

    >
    > > >typedefstruct Table{
    > > >     int sizeTable;
    > > >     unsigned sizeData;
    > > >     int (*diff)();
    > > >     unsigned (*hash)();
    > > >     void *(*copy)();
    > > >     void (*free)();
    > > > } * Table;

    >
    > > This is what you said. However pointers to void and pointers to structs
    > > are different things for the simple reason that void and struct are
    > > different.

    >
    > > Also hiding pointers behind atypedefis generally considered a bad thing.
    > > --
    > > Flash Gordon-


    don't quote sigs (the bit after the "-- ")


    --
    Nick Keighley
    Nick Keighley, May 6, 2008
    #5
  6. Re: previous declaration of Table was here / conflicting types for

    "Michael.Z" <> writes:

    > The Table.c was required to be implemented as generic type. If I am
    > right, Table is declared as void * in header file, the reason is that,
    > when used later on, it can be casted to any other type of pointers.
    >
    > The implementation of Table in Table.c was defined as pointer to
    > struct Table, because I need to implement the members of Table.
    >
    > My professor told us, void * in header indicates a generic type.
    > He has some sample codes where List was typedef'd void pointer but the
    > definition was struct List Pointer:


    First, the more common way to "hide the implementation" is simply to
    declare your functions as using a 'struct Table *' (as has already
    been explained by Flash Gordon).

    Secondly, this does not stop you writing generic functions that have a
    'void *' parameter. You can pass a 'struct Table *' where a 'void *'
    is expected when is important to do so.

    There is no obvious advantage to making the Table generic (in that
    sense) rather than simply hidden. In fact there is a positive
    *disadvantage* to doing that -- you loose all the type-checking. It
    is usually much better to stick with hidden (incomplete) struct
    pointers right up to the point where you are *forced* to start using
    'void *'.

    Your professor may have a reason for doing this, but it does seem like
    a wise choice from the sample you posted.

    --
    Ben.
    Ben Bacarisse, May 6, 2008
    #6
  7. Michael.Z

    Michael.Z Guest

    Re: previous declaration of Table was here / conflicting types for

    On May 6, 1:21 am, Nick Keighley <>
    wrote:
    > On 6 May, 03:33, "Michael.Z" <> wrote:
    >
    > > Hi Flash Gordon:
    > > The Table.c was required to be implemented as generic type.

    >
    > I'm not sure what a "generic type" is and I have been programming
    > for quite a while.
    >
    > > If I am
    > > right, Table is declared as void * in header file, the reason is that,
    > > when used later on, it can be casted to any other type of pointers.

    >
    > It may be you trying to hide implementation details from users
    > of your code. The outside world uses a void* and your
    > code (the library) casts it to the right type before use.
    > This is good. The internal data structure can change
    > without causing a recompile of the user code.
    >
    > /* pippo.h */typedefvoid* Table_handle;
    > Table_handle create();
    > void befunge (Table_handle);
    >
    > /* pippo.c */
    > void befunge (Table_handle handle)
    > {
    > Table* table = (Table*)handle;
    > ...
    >
    > }
    >
    > /* user.c */
    > int main (void)
    > {
    > Table_handle* my_table;
    > my_table = create();
    > befunge(my_table);
    > return 0;
    >
    > }
    >
    > The point is I *don't* try and have two differing
    > definitions of Table.
    >
    > > The implementation of Table in Table.c was defined as pointer to
    > > struct Table, because I need to implement the members of Table.

    >
    > > My professor told us, void * in header indicates a generic type.
    > > He has some sample codes where List wastypedef'd void pointer but the
    > > definition was struct List Pointer:

    >
    > so he had two different types didn't he?
    >
    >
    >
    > > /* Header file List.h*/
    > > #ifndef LIST_H
    > > #define LIST_H

    >
    > > #include "bool.h"

    >
    > > typedefvoid * List ;
    > > typedefvoid * DataL ;
    > > typedefvoid * ListIt ;

    >
    > > List makeList ( int , void * (*copy)() , void (*free)() ) ;
    > > void freeList ( List ) ;
    > > void clearList ( List ) ;

    >
    > > boolean accessList ( List , DataL , int ) ;
    > > int lengthList ( List ) ;

    >
    > > boolean accessHead ( List , DataL ) ;
    > > boolean insertHead ( List , DataL ) ;
    > > boolean deleteHead ( List , DataL ) ;

    >
    > > /* not all the header file is copied here*/

    >
    > > /* List.c */

    >
    > > #include "bool.h"
    > > #include <stdio.h>
    > > #include <stdlib.h>

    >
    > > #ifndef DATA
    > > #define DATA
    > >typedefvoid * Data ;
    > > #endif

    >
    > >typedefstruct ListNode {
    > > struct ListNode * next ; /* reference to following ListNode */
    > > struct ListNode * previous ; /* reference to preceding ListNode */
    > > Data dptr ;

    >
    > > } ListNode ;

    >
    > >typedefstruct List {
    > > ListNode * head ; /* Head end of List */
    > > ListNode * tail ; /* Tail end of List */
    > > int _lengthList ; /* number of items within List */
    > > int _sizeData ; /* byte size of data to be stored */
    > > void (*_freeData)( ) ; /* returns data item to heap */
    > > void * (*_copyData)( ) ; /* copies data item to another */

    >
    > > } * List ;

    >
    > arg!!!
    >
    > don't top post. Please put your reply after the text you are
    > replying to.
    >
    >
    >
    > > On May 3, 2:32 am, Flash Gordon <> wrote:

    >
    > > > Michael.Z wrote, On 03/05/08 08:22:

    >
    > > > > Anyone who can help:

    >
    > > > > Given a Table.h file I am writing a Table.c file.
    > > > > I keep getting the compile error:

    >
    > > > > previous declaration of Table was here / conflicting types for

    >
    > > > > I think the problem was the result of two pieces of code.
    > > > > First:typedefstruct Table; /* in Table.c*/

    >
    > > > This says that Table is a struct.

    >
    > > > > Second: struct Table { /*struct definition */ } *Table; /* in
    > > > > Table.h */

    >
    > > > This says it is a pointer to a struct, that is what the * means.

    >
    > > > > How can I solve the problems?

    >
    > > > By not providing different definitions.

    >
    > > > > Here are the two files

    >
    > > > <snip>

    >
    > > > >typedefvoid * Table ;

    >
    > > > This is not what you said you had and is defining table as yet another type.

    >
    > > > <snip>

    >
    > > > >typedefstruct Table{
    > > > > int sizeTable;
    > > > > unsigned sizeData;
    > > > > int (*diff)();
    > > > > unsigned (*hash)();
    > > > > void *(*copy)();
    > > > > void (*free)();
    > > > > } * Table;

    >
    > > > This is what you said. However pointers to void and pointers to structs
    > > > are different things for the simple reason that void and struct are
    > > > different.

    >
    > > > Also hiding pointers behind atypedefis generally considered a bad thing.
    > > > --
    > > > Flash Gordon-

    >
    > don't quote sigs (the bit after the "-- ")
    >


    Hi Nick,

    Thanks so much for your reply and your advice for not top posting and
    not quote signature, I am new to this, let me know if I need more
    further improvements.

    Regarding to your post:
    >
    > so he had two different types didn't he?
    >
    >


    He did have two different types. Its "void *" in header file while
    "struct List *" in List.c;
    eg.
    /*List.h*/
    typedef void *List;

    /*List.c*/
    typedef struct List{....} *List;

    However there was no conflicting type error, the reason is he did not
    include file "List.h" in his "List.c".

    So I removed #include "Table.h" from my "Table.c", it complied well.
    Regards.
    Michel Zhang
    Michael.Z, May 7, 2008
    #7
  8. Michael.Z

    Flash Gordon Guest

    Re: previous declaration of Table was here / conflicting types for

    Michael.Z wrote, On 07/05/08 09:05:
    > On May 6, 1:21 am, Nick Keighley <>
    > wrote:


    <snip>

    > Regarding to your post:
    >> so he had two different types didn't he?

    >
    > He did have two different types. Its "void *" in header file while
    > "struct List *" in List.c;
    > eg.
    > /*List.h*/
    > typedef void *List;
    >
    > /*List.c*/
    > typedef struct List{....} *List;


    In that case what he provided was wrong. No ifs, not buts, it is just
    plain wrong. Wrong as in the definition of the language says that it is
    wrong.

    > However there was no conflicting type error,


    The error is still there, it is just hidden from the compiler so that it
    does not tell you about it. It is no more correct than driver the wrong
    way up a one way street at 100mph is legal if you do not get caught. Not
    being caught does not make it legal.

    > the reason is he did not
    > include file "List.h" in his "List.c".


    That, whilst not forbidden by the language, is generally considered to
    be bad practice. The reason it is considered to be bad practice is
    specifically *because* it hides errors like this.

    > So I removed #include "Table.h" from my "Table.c", it complied well.


    Compiling does not make it correct. If you have a good relationship with
    your tutor/lecturer/teacher you should explain to your lecturer that his
    code is wrong. If your relationship is not good enough to get away with
    that you should ask him why it fails to compile if the header file is
    not included (but avoid arguing the point if it will affect your
    grades). In either case, you should take any code presented with at
    least a pinch of salt, and if he does not understand the problem you
    should take the entire course with a whole keg of salt as what you are
    being taught is wrong.
    --
    Flash Gordon
    Flash Gordon, May 7, 2008
    #8
  9. Re: previous declaration of Table was here / conflicting types for

    [snip: On May 6, 3:32 am, Ben Bacarisse <> wrote:
    > "Michael.Z" <> writes:
    > > The Table.c was required to be implemented as generic type. If I am
    > > right, Table is declared as void * in header file, the reason is that,
    > > when used later on, it can be casted to any other type of pointers.

    >
    > > The implementation of Table in Table.c was defined as pointer to
    > > struct Table, because I need to implement the members of Table.

    > ]
    > > My professor told us, void * in header indicates a generic type.
    > > He has some sample codes where List wastypedef'd void pointer but the
    > > definition was struct List Pointer:

    >
    > First, the more common way to "hide the implementation" is simply to
    > declare your functions as using a 'struct Table *' (as has already
    > been explained by Flash Gordon).
    >
    > Secondly, this does not stop you writing generic functions that have a
    > 'void *' parameter. You can pass a 'struct Table *' where a 'void *'
    > is expected when is important to do so.


    I just want to make sure I got you right.You are suggesting:
    typedef struct Table{ ...} Table;
    Table * makeTable( void* size, void * data);

    > There is no obvious advantage to making the Table generic (in that
    > sense) rather than simply hidden. In fact there is a positive
    > *disadvantage* to doing that -- you loose all the type-checking. It


    I don't quit understand this part.
    "generic(in that sense)": refers to what I said about my professors
    way.
    vs
    "simply hidden": the above example. Table * makeTable( void* size,
    void * data);

    > is usually much better to stick with hidden (incomplete) struct
    > pointers right up to the point where you are *forced* to start using
    > 'void *'.



    an example of being *forced* would be:

    void useTable(*void myTable){
    Table * makeTable = (Table *)myTable;

    }

    if my example is not right, any chance you can give me correct one?



    >
    > Your professor may have a reason for doing this, but it does seem like
    > a wise choice from the sample you posted.
    >
    > --
    > Ben.


    "
    Michael.Zhang, May 9, 2008
    #9
  10. Re: previous declaration of Table was here / conflicting types for

    "Michael.Zhang" <> writes:

    > [snip: On May 6, 3:32 am, Ben Bacarisse <> wrote:
    >> "Michael.Z" <> writes:
    >> > The Table.c was required to be implemented as generic type. If I am
    >> > right, Table is declared as void * in header file, the reason is that,
    >> > when used later on, it can be casted to any other type of pointers.

    >>
    >> > The implementation of Table in Table.c was defined as pointer to
    >> > struct Table, because I need to implement the members of Table.

    >> ]
    >> > My professor told us, void * in header indicates a generic type.
    >> > He has some sample codes where List wastypedef'd void pointer but the
    >> > definition was struct List Pointer:

    >>
    >> First, the more common way to "hide the implementation" is simply to
    >> declare your functions as using a 'struct Table *' (as has already
    >> been explained by Flash Gordon).
    >>
    >> Secondly, this does not stop you writing generic functions that have a
    >> 'void *' parameter. You can pass a 'struct Table *' where a 'void *'
    >> is expected when is important to do so.

    >
    > I just want to make sure I got you right.You are suggesting:
    > typedef struct Table{ ...} Table;
    > Table * makeTable( void* size, void * data);


    Why would a parameter called size be a void *? That is possible, but
    I can't say that that is what I was suggesting.

    The function makeTable does sound very generic so it is not a good
    example. Let's say we have a linked list. To make it generic we
    could insist that items to be added are passed as void *:

    List *listAdd(List *l, void *item);

    We can add a table to a list like this:

    List *my_list = makeList(...);
    Table *tp = makeTable(...);
    ...
    my_list = listAdd(my_list, tp);

    We can insert a list into another list:

    List *other = ...;
    ...
    my_list = listAdd(my_list, other);

    with not a cast in sight.

    >> There is no obvious advantage to making the Table generic (in that
    >> sense) rather than simply hidden. In fact there is a positive
    >> *disadvantage* to doing that -- you loose all the type-checking. It

    >
    > I don't quit understand this part.
    > "generic(in that sense)": refers to what I said about my professors
    > way.
    > vs
    > "simply hidden": the above example. Table * makeTable( void* size,
    > void * data);


    That is right. Hiding the details of a struct is a very common and
    important technique in C, but doing that by making it look like the
    function return a void * is wrong.

    From what I've seen so far your teacher's method is just plain wrong.
    As a (now ex-) teacher myself, I am loath to be dogmatic -- maybe you
    are being asked to write non-portable code for some very specific
    reason, but declaring a function to return void * in one place and
    defining it to return a Table * in another is undefined behaviour and
    will break on some systems.

    >> is usually much better to stick with hidden (incomplete) struct
    >> pointers right up to the point where you are *forced* to start using
    >> 'void *'.

    >
    >
    > an example of being *forced* would be:
    >
    > void useTable(*void myTable){
    > Table * makeTable = (Table *)myTable;
    >
    > }
    >
    > if my example is not right, any chance you can give me correct one?


    I can't follow that at all. First,did you mean:

    void useTable(void *myTable) {
    Table * makeTable = (Table *)myTable;

    }

    If, so the cast is not needed. But anyway, why would you not know the
    type of the parameter to a function called useTable? It sounds like
    it will always be passed a Table *.

    You are forced to use void * when you don't know the type. See
    the example about of a generic list. Anything can be added to it
    because the item to be added is simply a void *.

    --
    Ben.
    Ben Bacarisse, May 10, 2008
    #10
  11. Michael.Z

    Chris Torek Guest

    Re: previous declaration of Table was here / conflicting types for

    In article <>
    Michael.Zhang <> wrote:
    [in a reply to Ben Bacarisse]
    >I just want to make sure I got you right.You are suggesting:
    >typedef struct Table{ ...} Table;
    >Table * makeTable( void* size, void * data);


    I can only speak for myself, not for Ben Bacarisse, but I rather
    doubt that is what he is suggesting.

    In the absence of additional details, here is how *I* might do
    this. Note that I prefer not to use "typedef" -- which does not
    actually define types -- at all, but there are some "pro-typedef"
    reasons. See <http://web.torek.net/torek/c/types2.html> for
    details on this.

    In this particular case, I might have a "table.h" file. In table.h,
    one would find, e.g., the following (assuming the table is indexed
    by simple "row,column" integer-pairs):

    struct table;

    struct table *table_create(void);
    void *table_lookup(struct table *table, int row, int col);
    int table_insert(struct table *table, int row, int col, void *data);
    void *table_delete(struct table *table, int row, int col);
    void table_iterate(struct table *table, void *aux,
    void (*iter)(struct table *table, void *aux,
    int row, int col, void *data));
    void table_destroy(struct table *table, int free_all_data);

    Note that there is no "{" after "struct table". This means that
    the entire contents of a "struct table" are hidden. So where are
    they? The answer is: in table.c (or perhaps in table-impl.h, which
    is then #include-ed by table1.c and table2.c, if for some reason
    "table.c" is not suitable to be used as a single file).

    "Table clients", as it were, now have no idea what is *inside* a
    table. They only know that they can "create" one, do "lookup"
    operations, do "insert" operations, do "delete" operations, ask to
    "iterate" a function (of their choosing) over all table entries,
    and "destroy" a table (with, in this case, optional automatic calls
    to free() on each table item, so that they need not write a "freeing
    iterator").

    There is still quite a bit exposed here. For instance, this makes
    it clear that tables are indexed exclusively by integral (row,column)
    pairs. We must also decide whether "iterate" is called for "empty"
    entries (e.g., if there is a row 7, but only a column 3 in row 7
    -- even though other rows have columns 0 through 5 -- does the
    user's iterator get called with NULL entries for columns 0, 1, 2,
    4, and 5 on row 7?). Nonetheless, the actual details of how the
    tables are implemented are safely tucked away: clients know only
    as much about tables as you choose to expose, while the "table
    server" code (in table.c) sees all the details.

    (Also, rather than "table", the above should probably called a
    "sparse matrix" anyway. "Tables" might actually instead be hash
    tables that implement what one uses associative arrays for in
    languages like awk, for instance.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
    Chris Torek, May 10, 2008
    #11
  12. Re: previous declaration of Table was here / conflicting types for

    [snip:
    On May 9, 10:43 pm, Chris Torek <> wrote:
    > In article <>Michael.Zhang <> wrote:
    >
    > [in a reply to Ben Bacarisse]
    >
    > >I just want to make sure I got you right.You are suggesting:
    > >typedef struct Table{ ...} Table;
    > >Table * makeTable( void* size, void * data);

    >
    > I can only speak for myself, not for Ben Bacarisse, but I rather
    > doubt that is what he is suggesting.
    >
    > In the absence of additional details, here is how *I* might do
    > this.  Note that I prefer not to use "typedef" -- which does not
    > actually define types -- at all, but there are some "pro-typedef"
    > reasons.  See <http://web.torek.net/torek/c/types2.html> for
    > details on this.
    >
    > In this particular case, I might have a "table.h" file.  In table.h,
    > one would find, e.g., the following (assuming the table is indexed
    > by simple "row,column" integer-pairs):
    >
    >     struct table;
    >
    >     struct table *table_create(void);
    >     void *table_lookup(struct table *table, int row, int col);
    >     int table_insert(struct table *table, int row, int col, void *data);
    >     void *table_delete(struct table *table, int row, int col);
    >     void table_iterate(struct table *table, void *aux,
    >         void (*iter)(struct table *table, void *aux,
    >                      int row, int col, void *data));
    >     void table_destroy(struct table *table, int free_all_data);
    >
    > Note that there is no "{" after "struct table".  This means that
    > the entire contents of a "struct table" are hidden.  So where are
    > they?  The answer is: in table.c (or perhaps in table-impl.h, which
    > is then #include-ed by table1.c and table2.c, if for some reason
    > "table.c" is not suitable to be used as a single file).
    >
    > "Table clients", as it were, now have no idea what is *inside* a
    > table.  They only know that they can "create" one, do "lookup"
    > operations, do "insert" operations, do "delete" operations, ask to
    > "iterate" a function (of their choosing) over all table entries,
    > and "destroy" a table (with, in this case, optional automatic calls
    > to free() on each table item, so that they need not write a "freeing
    > iterator").
    >
    > There is still quite a bit exposed here.  For instance, this makes
    > it clear that tables are indexed exclusively by integral (row,column)
    > pairs.  We must also decide whether "iterate" is called for "empty"
    > entries (e.g., if there is a row 7, but only a column 3 in row 7
    > -- even though other rows have columns 0 through 5 -- does the
    > user's iterator get called with NULL entries for columns 0, 1, 2,
    > 4, and 5 on row 7?).  Nonetheless, the actual details of how the
    > tables are implemented are safely tucked away: clients know only
    > as much about tables as you choose to expose, while the "table
    > server" code (in table.c) sees all the details.
    >
    > (Also, rather than "table", the above should probably called a
    > "sparse matrix" anyway.  "Tables" might actually instead be hash
    > tables that implement what one uses associative arrays for in
    > languages like awk, for instance.)
    > --
    > In-Real-Life: Chris Torek, Wind River Systems
    > Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W)  +1 801 277 2603
    > email: gmail (figure it out)      http://web.torek.net/torek/index.html


    ]


    OFF TOPIC to previous discussion,reason being don't know where I
    should post this question.

    Thanks very much for all your replies. Seems most of you have a lot of
    experiences in computer science. I might just ask you some questions
    that I couldn't get advice from.

    my problem is that I love computer science,i know how do study,but I
    dont understand the material well enough, I am terrible computer
    science student, I don't know what's gonna happen to person like me
    after graduating with a GPA around C in CS.

    I love computer science, cos I like programming, I enjoy debugging,
    tracing down the logic and fix the bug. I am fancinated by the
    algorithms being tought and problem solving skills I gained.
    but, I am not doing well at all in my courses. My peer can finish a
    programming assignment within 3 or 4 hours without help from TA at
    all; while I can't progress much without help from others, it might
    take me well over 20 hours even with help from others. I am not
    efficient at programming at all.

    Right now, I am taking a data structure and an algorithm course(Graph
    theory,divide and conquer,danamic programming). I might barely pass my
    data structure course, but fail the algorithm.

    Before adding CS as another major, I studied some business courses
    from accoutning and information systems,I did pretty well in thoese
    courses,I believe I have a good study habbit.Lately, I have to admit
    that I have to be a lot smarter to study Computer Science and I am not
    at that level. I am sitting on the fence and don't know if I should
    continue with CS(have taken 8 CS courses) or drop out of this major.

    Any advice or opinion would be greatly appreciated.
    Michael.Zhang, May 11, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    4,600
  2. dentzigui
    Replies:
    8
    Views:
    4,655
    Seebs
    Nov 1, 2009
  3. Michael Doubez
    Replies:
    11
    Views:
    881
    James Kanze
    Mar 26, 2011
  4. Skybuck Flying
    Replies:
    5
    Views:
    623
    ImpalerCore
    Nov 29, 2011
  5. K' Dash
    Replies:
    6
    Views:
    62
    K' Dash
    Jun 6, 2014
Loading...

Share This Page