best way to declare struct to be used in other c and c++ files

Discussion in 'C Programming' started by Tammy, Sep 6, 2008.

  1. Tammy

    Tammy Guest

    Hello all,

    I am wondering what is the best way to declare a struct to be used in
    other c and c++ files. Such as for a C API that will be used by
    others.

    1. Declaring the typedef and the struct in the header file and
    including this file in all source files that need it? For example:

    mystruct.h

    typedef mystruct mystruct_t;

    struct mystruct {
    int x;
    char c;
    };

    -OR-
    2. Declaring the typedef in a header file and declaring the struct in
    the .c file ( I am not certain that this will work). For example:

    mystruct.h

    typedef mystruct mystruct_t;


    mystruct.c

    #include "mystruct.h"

    struct mystruct {
    int x;
    char c;
    };

    ......(other code using the structure)

    -OR-

    3. Other methods??

    Thanks in advance for your help,
    Tammy
    Tammy, Sep 6, 2008
    #1
    1. Advertising

  2. Tammy

    Ian Collins Guest

    Tammy wrote:
    > Hello all,
    >
    > I am wondering what is the best way to declare a struct to be used in
    > other c and c++ files. Such as for a C API that will be used by
    > others.
    >
    > 1. Declaring the typedef and the struct in the header file and
    > including this file in all source files that need it? For example:
    >
    > mystruct.h
    >
    > typedef mystruct mystruct_t;
    >
    > struct mystruct {
    > int x;
    > char c;
    > };
    >

    This is the normal way for a public structure declaration, with the
    addition of a conditionally compiled extern "C" wrapper for the benefit
    of C++ files that include the header.

    > -OR-
    > 2. Declaring the typedef in a header file and declaring the struct in
    > the .c file ( I am not certain that this will work). For example:
    >
    > mystruct.h
    >
    > typedef mystruct mystruct_t;
    >
    >
    > mystruct.c
    >
    > #include "mystruct.h"
    >
    > struct mystruct {
    > int x;
    > char c;
    > };
    >

    If you want the details of mystruct to remain hidden, this is also
    common practice.

    --
    Ian Collins.
    Ian Collins, Sep 6, 2008
    #2
    1. Advertising

  3. Tammy <> writes:
    > I am wondering what is the best way to declare a struct to be used in
    > other c and c++ files. Such as for a C API that will be used by
    > others.
    >
    > 1. Declaring the typedef and the struct in the header file and
    > including this file in all source files that need it? For example:
    >
    > mystruct.h
    >
    > typedef mystruct mystruct_t;
    >
    > struct mystruct {
    > int x;
    > char c;
    > };


    That needs to be "typedef struct mystruct mystruct_t;".

    > -OR-
    > 2. Declaring the typedef in a header file and declaring the struct in
    > the .c file ( I am not certain that this will work). For example:
    >
    > mystruct.h
    >
    > typedef mystruct mystruct_t;
    >
    >
    > mystruct.c
    >
    > #include "mystruct.h"
    >
    > struct mystruct {
    > int x;
    > char c;
    > };
    >
    > .....(other code using the structure)

    [...]

    It depends on whether the client code needs to see the members and/or
    declare objects of the type.

    With the second approach struct mystruct, and therefore mystruct_t, is
    an incomplete type as far as anything with a #include "mystruct.h" is
    concerned. That means that client code can declare and manipulate
    pointers to the type, but it can't declare objects of the type or
    refer to its members.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 6, 2008
    #3
  4. pete <> writes:
    > Tammy wrote:
    >> Hello all,
    >> I am wondering what is the best way to declare a struct to be used in
    >> other c and c++ files. Such as for a C API that will be used by
    >> others.
    >> 1. Declaring the typedef and the struct in the header file and
    >> including this file in all source files that need it?

    >
    > I define the typedef in the header file
    > and include this file in all source files that need it.
    >
    > http://www.mindspring.com/~pfilandr/C/e_driver/e_driver.h
    >
    > #define E_TYPE struct {char array[40]; d_type data;} e_type
    > #define D_TYPE long double d_type
    > typedef D_TYPE;
    > typedef E_TYPE;
    >
    > http://www.mindspring.com/~pfilandr/C/e_driver/


    That's a very odd use of macros; I find it extremely counterintuitive.

    Looking at the web page, it makes *some* sense in context. You have
    (I'm abbreviating this):

    #define STRUCTURES 0 /* 0 or 1, This is the line to change */

    #if STRUCTURES == 0 /* Not this one */

    #define E_TYPE long unsigned e_type
    #define D_TYPE long unsigned d_type

    #else

    #define E_TYPE struct {char array[40]; d_type data;} e_type
    #define D_TYPE long double d_type

    #endif

    typedef D_TYPE;
    typedef E_TYPE;

    I'm sure there's some good reason to conditionally define E_TYPE and
    D_TYPE either as unsigned long or as a struct and a long double; I
    haven't read enough of the code to understand what that reason might
    be. But I definitely wouldn't write it that way. I'd probably write
    something more like this:

    #undef STRUCTURES /* defined or undefined

    #ifdef STRUCTURES

    typedef long double d_type;
    typedef struct {char array[40]; d_type data;} e_type;

    #else

    typedef unsigned long d_type;
    typedef unsigned long e_type;

    #endif

    In any case, your code sample illustrates the use of the preprocessor
    to conditionally define types in one of two different ways, which
    isn't what the OP was asking about.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 6, 2008
    #4
  5. Tammy

    ac Guest

    On Sat, 06 Sep 2008 07:50:47 +0100, pete <> wrote:

    > I prefer to have the readily changeable parts of the program,
    > be macros.
    > The program also prints out the stringized macros.
    >
    > The proper use of of the e_type interface,
    > is to define at least these three macros in a header file,
    > (there may be other macros depending on the sort algorithm)
    > for sorting functions which can then be used to sort
    > arrays of elements of any type, including arrays of arrays:
    >
    > #define E_TYPE
    > #define MOV(A, B)
    > #define GT(A, B)
    >
    > For example, I was looking at:
    > http://www.pobox.com/~qed/sort.html
    > which redirected me to
    > http://www.azillionmonkeys.com/qed/sort.html
    > and I downloaded the program at this link:
    > http://www.azillionmonkeys.com/qed/sorttest.c
    >
    > and since I like to race sorting functions,
    > I changed the name of the program to pq_test
    > and replaced the definition of main with this:


    Maybe a potential problem with this E_TYPE is we can only define one
    etype_t in one C source file, which means we cannot sort an integer array
    and a double array in the same C source file. Is that true? I think a
    better way to achieve generic types is this example, using token
    concatenation:

    http://www.freewebs.com/attractivechaos/ksort.h.html
    http://www.freewebs.com/attractivechaos/ksort_test.c.html

    No function calls are made for comparisons, either.

    BTW, it seems that you have implemented really efficient sorting
    functions! How is it compared to STL sort?

    Thanks,

    -ac
    ac, Sep 6, 2008
    #5
  6. Tammy

    ac Guest

    On Sun, 07 Sep 2008 03:20:21 +0100, pete <> wrote:

    > That's very interesting to me.
    > I have no experience with ##.
    > Maybe it's about time for me to become more familiar with it.


    If you are interested in this method, you may also have a look at this
    header file:

    http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/tree.h

    This file is part of freebsd. It implements a splay tree and a rb tree,
    allowing for generic types.

    -ac
    ac, Sep 7, 2008
    #6
  7. pete <> wrote:
    > ...The proper use of of the e_type interface,
    > is to define at least these three macros in a header file,
    > (there may be other macros depending on the sort algorithm)
    > for sorting functions which can then be used to sort
    > arrays of elements of any type, including arrays of arrays:
    >
    > #define E_TYPE
    > #define MOV(A, B)
    > #define GT(A, B)


    I prefer to make the configurable components of the sort
    template functions as macro parameters. [The following is
    just proof of concept. File break up requires (re)insertion
    of include guards and other details.]


    %type sort.c
    /* --------- */
    /* pp_util.h */
    /* --------- */
    #define pp_cat(a, b) a ## b
    #define pp_concat(a, b) pp_cat(a, b)

    #define pp_t(T) pp_concat(T, _t)
    typedef int int_t; /* and the rest */

    #define pp_lt(a, b) ((a) < (b))
    #define pp_assign(a, b) ((a) = (b))
    #define pp_memcpy(a, b) memcpy(a, b, sizeof(a))


    /* --------- */
    /* pp_sort.h */
    /* --------- */

    /* #include "pp_util.h" */
    #include <stddef.h>

    #define pp_sort(T, a, n) \
    pp_concat(sort_, T)(a, n)

    #define pp_decl_sort(T) \
    void pp_concat(sort_, T)(pp_t(T) *, size_t)

    /* trivial for sake of demo */
    #define pp_defn_sort(T, lt_pp, assign_pp) \
    void pp_concat(sort_, T)( pp_t(T) *a, \
    size_t n ) \
    { \
    size_t i, j, k; \
    pp_t(T) t; \
    \
    for (i = 0; i < n - 1; i++) \
    { \
    for (k = i, j = i + 1; j < n; j++) \
    if (lt_pp(a[j], a)) \
    k = j; \
    \
    if (k != i) \
    { \
    assign_pp(t, a); \
    assign_pp(a, a[k]); \
    assign_pp(a[k], t ); \
    } \
    } \
    }

    pp_decl_sort(int); /* built-ins */


    /* ----------- */
    /* gauss_int.h */
    /* ----------- */

    typedef int gauss_int_t[2];
    pp_decl_sort(gauss_int);


    /* ------ */
    /* main.c */
    /* ------ */

    /* #include "gauss_int.h" */
    /* #include "pp_sort.h" */
    #include <stdio.h>

    #define countof(x) \
    ((size_t) (sizeof(x)/sizeof*(x)))

    int main(void)
    {
    int ai[] = { 2, -4, 8, -16 };
    gauss_int_t gi[] = { { 2, -4},
    { -8, 16 },
    {32, -64},
    {-128, 256} };
    size_t i;

    /* Integers */
    for (i = 0; i < countof(ai); i++)
    printf(" %d", ai);
    puts("");

    sort_int(ai, countof(ai));

    for (i = 0; i < countof(ai); i++)
    printf(" %d", ai);
    puts("\n");

    /* Gaussian Integers */
    for (i = 0; i < countof(ai); i++)
    printf(" (%d, %d)", gi[0], gi[1]);
    puts("");

    sort_gauss_int(gi, countof(gi));

    for (i = 0; i < countof(ai); i++)
    printf(" (%d, %d)", gi[0], gi[1]);
    puts("");

    return 0;
    }


    /* ------ */
    /* sort.c */
    /* ------ */

    /* #include "pp_sort.h" */

    pp_defn_sort(int, pp_lt, pp_assign)


    /* ----------- */
    /* gauss_int.c */
    /* ----------- */

    /* #include "pp_util.h" */
    /* #include "pp_sort.h" */
    #include <string.h>

    #define pp_gauss_lt(a, b) \
    ( pp_lt( (a)[0], (b)[0] ) ? 1 \
    : pp_lt( (b)[0], (a)[0] ) ? 0 \
    : pp_lt( (a)[1], (b)[1] ) )

    pp_defn_sort(gauss_int, pp_gauss_lt, pp_memcpy)

    % acc sort.c

    % a
    2 -4 8 -16
    -16 -4 2 8

    (2, -4) (-8, 16) (32, -64) (-128, 256)
    (-128, 256) (-8, 16) (2, -4) (32, -64)

    %

    --
    Peter
    Peter Nilsson, Sep 8, 2008
    #7
    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:
    20
    Views:
    2,184
  2. David T. Ashley
    Replies:
    6
    Views:
    526
    Tim Rentsch
    Dec 5, 2004
  3. Geetesh
    Replies:
    19
    Views:
    603
    Yakov Lerner
    Mar 3, 2004
  4. Chris Fogelklou
    Replies:
    36
    Views:
    1,354
    Chris Fogelklou
    Apr 20, 2004
  5. David T. Ashley
    Replies:
    6
    Views:
    373
    Tim Rentsch
    Dec 5, 2004
Loading...

Share This Page