A question about global struct variable as a fuction's parameter

Discussion in 'C Programming' started by PCHOME, Apr 12, 2005.

  1. PCHOME

    PCHOME Guest

    Hello! I am working on dividing a single C file into several files.
    Now I encounter a problem about the global variables
    and can not find a way to solve it.
    All global variables and codes used to be in that single file, that
    worked OK. But when I divdie that file into several ones, I
    have many "invalid use of undefined type" errors.

    The four files are main.c, main.h, readLP.h, and readLP.c.

    In readLP.h
    I have:

    #define MAX_NUMROWS 181010
    #define MAX_NUMCOLS 201
    #define MAX_NUMNZ 9000000
    ....

    typedef struct Polytope {
    int rmatbeg[MAX_NUMROWS];
    int rmatind[MAX_NUMNZ];
    double rmatval[MAX_NUMNZ];
    double rhs[MAX_NUMROWS];
    char sense[MAX_NUMROWS];
    double cosine[MAX_NUMROWS];
    double norm[MAX_NUMROWS];
    /* char *rowname[MAX_NUMROWS]; */
    } a_polytope, aa_polytope;
    ....

    and in main.h, I have:
    ....
    extern struct Polytope a_polytope, aa_polytope ;

    in main.c , if the external variable a_polytope is
    used as a function's parameters such as :
    status = CPXaddrows (env, lp, 0, num_rows, num_nonzero,
    a_polytope.rhs, a_polytope.sense,a_polytope.rmatbeg,
    a_polytope.rmatind, a_polytope.rmatval, NULL, NULL);
    /* this is a CPLEX callable library function */

    I will get "invalid use of undefined type `struct
    Polytope'" error in compiling.
    It was working OK when all codes were in sigle file without using
    keyword "extern".

    If I change main.h into:
    ....
    extern struct Polytope a_polytope, aa_polytope ;
    struct Polytope *pa_polytope, *paa_polytope ;
    ....
    and also change main.c into
    pa_polytope = &a_polytope ;
    status = CPXaddrows (env, lp, 0,num_rows, num_nonzero,
    pa_polytope->rhs,pa_polytope->sense,pa_polytope->rmatbeg,
    pa_polytope->rmatind,pa_polytope->rmatval,
    NULL, NULL);

    I will get "dereferencing pointer to incomplete type"
    four times for each pa_polytope->xxxx above.

    Does anyone have a suggestion?

    Thank you so much!
    PCHOME, Apr 12, 2005
    #1
    1. Advertising

  2. PCHOME

    Eric Sosman Guest

    PCHOME wrote:
    > Hello! I am working on dividing a single C file into several files.
    > Now I encounter a problem about the global variables
    > and can not find a way to solve it.
    > All global variables and codes used to be in that single file, that
    > worked OK. But when I divdie that file into several ones, I
    > have many "invalid use of undefined type" errors.
    >
    > The four files are main.c, main.h, readLP.h, and readLP.c.
    >
    > In readLP.h
    > I have:
    >
    > #define MAX_NUMROWS 181010
    > #define MAX_NUMCOLS 201
    > #define MAX_NUMNZ 9000000
    > ...
    >
    > typedef struct Polytope {
    > int rmatbeg[MAX_NUMROWS];
    > int rmatind[MAX_NUMNZ];
    > double rmatval[MAX_NUMNZ];
    > double rhs[MAX_NUMROWS];
    > char sense[MAX_NUMROWS];
    > double cosine[MAX_NUMROWS];
    > double norm[MAX_NUMROWS];
    > /* char *rowname[MAX_NUMROWS]; */
    > } a_polytope, aa_polytope;


    Are you sure this is your code? It may be, of
    course, but if so it doesn't mean what I suspect you
    intend it to mean. This declaration says "Here is
    what a `struct Polytope' looks like, and here are two
    aliases for `struct Polytope' -- that is, any time I
    write `a_polytope' or `aa_polytope' it is just as if
    I had written out `struct Polytope' in full."

    Note that this declaration does *not* declare or
    define any variables of the type `struct Polytope' --
    it just describes `struct Polytope' and creates two
    aliases for it.

    > ...
    >
    > and in main.h, I have:
    > ...
    > extern struct Polytope a_polytope, aa_polytope ;


    This says "Somewhere else I will define two variables
    of type `struct Polytope' with these two names." However,
    nothing that you've shown actually defines any such
    variables.

    Another interesting point (the proximal cause of the
    diagnostics you're receiving) is that the description of
    what a `struct Polytope' looks like appears only in
    "readLP.h". If you include "main.h" in a file that doesn't
    also include "readLP.h", that description is not available.
    The compiler knows that `struct Polytope' is some kind of
    a struct type, but doesn't know anything about the elements
    that struct type contains: it doesn't know their names,
    their types, their sizes, or their arrangement within the
    struct. (You will eventually learn that such "incomplete
    types" can be useful in certain circumstances, but I think
    you may not be quite ready for that lesson yet.)

    > in main.c , if the external variable a_polytope is
    > used as a function's parameters such as :
    > status = CPXaddrows (env, lp, 0, num_rows, num_nonzero,
    > a_polytope.rhs, a_polytope.sense,a_polytope.rmatbeg,
    > a_polytope.rmatind, a_polytope.rmatval, NULL, NULL);
    > /* this is a CPLEX callable library function */
    >
    > I will get "invalid use of undefined type `struct
    > Polytope'" error in compiling.


    Right: Without "readLP.h", the compiler is ignorant of
    the internals of a `struct Polytope'. From the code as shown
    it might deduce that the struct has elements named `rhs' and
    `sense' and so on, but it has no idea what these names mean.

    > It was working OK when all codes were in sigle file without using
    > keyword "extern".


    Presumably because the complete declaration of `struct
    Polytope' was in that file, too. (But I suspect that the
    `typedef' is a recent and probably incorrect addition.)

    > If I change main.h into:
    > ...
    > extern struct Polytope a_polytope, aa_polytope ;
    > struct Polytope *pa_polytope, *paa_polytope ;
    > ...
    > and also change main.c into
    > pa_polytope = &a_polytope ;
    > status = CPXaddrows (env, lp, 0,num_rows, num_nonzero,
    > pa_polytope->rhs,pa_polytope->sense,pa_polytope->rmatbeg,
    > pa_polytope->rmatind,pa_polytope->rmatval,
    > NULL, NULL);
    >
    > I will get "dereferencing pointer to incomplete type"
    > four times for each pa_polytope->xxxx above.


    Right: The compiler knows of two `struct Polytope'
    variables ("Whatever *that* may be," says the compiler)
    named `a_polytope' and `aa_polytope'. It also knows of
    to pointers `pa_polytope' and `paa_polytope', defined
    locally, that can be made to point to those structs (and
    to others of the same type). But it's still without any
    information about "the insides" of the struct; loosely
    speaking, you've told it how to point "at" the struct as
    a whole, but not how to "reach inside."

    > Does anyone have a suggestion?


    Back to the C textbook, I think. There are enough
    misunderstandings on exhibit here that you're probably
    better off re-studying the fundamentals than trying to
    blunder ahead in flat-Earthian ignorance -- you wouldn't
    want to fall off the Edge, would you?

    --
    Eric Sosman, Apr 12, 2005
    #2
    1. Advertising

  3. PCHOME

    Darius Guest

    PCHOME wrote:
    > Hello! I am working on dividing a single C file into several files.
    > Now I encounter a problem about the global variables
    > and can not find a way to solve it.
    > All global variables and codes used to be in that single file, that
    > worked OK. But when I divdie that file into several ones, I
    > have many "invalid use of undefined type" errors.
    >
    > The four files are main.c, main.h, readLP.h, and readLP.c.
    >
    > In readLP.h
    > I have:
    >
    > #define MAX_NUMROWS 181010
    > #define MAX_NUMCOLS 201
    > #define MAX_NUMNZ 9000000
    > ...
    >
    > typedef struct Polytope {
    > int rmatbeg[MAX_NUMROWS];
    > int rmatind[MAX_NUMNZ];
    > double rmatval[MAX_NUMNZ];
    > double rhs[MAX_NUMROWS];
    > char sense[MAX_NUMROWS];
    > double cosine[MAX_NUMROWS];
    > double norm[MAX_NUMROWS];
    > /* char *rowname[MAX_NUMROWS]; */
    > } a_polytope, aa_polytope;
    > ...
    >
    > and in main.h, I have:
    > ...
    > extern struct Polytope a_polytope, aa_polytope ;
    >
    > in main.c , if the external variable a_polytope is
    > used as a function's parameters such as :
    > status = CPXaddrows (env, lp, 0, num_rows, num_nonzero,
    > a_polytope.rhs, a_polytope.sense,a_polytope.rmatbeg,
    > a_polytope.rmatind, a_polytope.rmatval, NULL, NULL);
    > /* this is a CPLEX callable library function */
    >
    > I will get "invalid use of undefined type `struct
    > Polytope'" error in compiling.
    > It was working OK when all codes were in sigle file without using
    > keyword "extern".
    >
    > If I change main.h into:
    > ...
    > extern struct Polytope a_polytope, aa_polytope ;
    > struct Polytope *pa_polytope, *paa_polytope ;
    > ...
    > and also change main.c into
    > pa_polytope = &a_polytope ;
    > status = CPXaddrows (env, lp, 0,num_rows, num_nonzero,
    > pa_polytope->rhs,pa_polytope->sense,pa_polytope->rmatbeg,
    > pa_polytope->rmatind,pa_polytope->rmatval,
    > NULL, NULL);
    >
    > I will get "dereferencing pointer to incomplete type"
    > four times for each pa_polytope->xxxx above.
    >
    > Does anyone have a suggestion?
    >
    > Thank you so much!


    refer eric's reply to understand what you did wrongly.
    now i'll tell you how can you correct this, i mean generally how its
    done.

    in readLP.h //remove typedef
    /*typedef*/ struct Polytope {
    int rmatbeg[MAX_NUMROWS];
    int rmatind[MAX_NUMNZ];
    double rmatval[MAX_NUMNZ];
    double rhs[MAX_NUMROWS];
    char sense[MAX_NUMROWS];
    double cosine[MAX_NUMROWS];
    double norm[MAX_NUMROWS];
    /* char *rowname[MAX_NUMROWS]; */
    } ;
    extern struct Polytope a_polytope, aa_polytope;

    in readLP.c
    #include "readLP.h"
    struct Polytope a_polytope, aa_polytope;

    in any other file -------->
    #include "readLp.h"
    // optionally you can declare extern struct Polytope a_polytope,
    aa_polytope;
    //its your wish as it has already been done when you include readLP.h

    rest is fine !!!
    ------------------
    i love C
    darius
    Darius, Apr 12, 2005
    #3
  4. PCHOME

    PCHOME Guest

    Eric Sosman wrote:

    >
    > Presumably because the complete declaration of `struct
    > Polytope' was in that file, too. (But I suspect that the
    > `typedef' is a recent and probably incorrect addition.)

    Yes. The `typedef' is a recent addition. I did not put it in my
    orginalcodes. I added it desperately after dozens of trials.



    > > Does anyone have a suggestion?

    >
    > Back to the C textbook, I think. There are enough
    > misunderstandings on exhibit here that you're probably
    > better off re-studying the fundamentals than trying to
    > blunder ahead in flat-Earthian ignorance -- you wouldn't
    > want to fall off the Edge, would you?
    >

    What C textbook will you suggest? I did look up at least 3
    C-textbooks, but none of them mentions clearly about the topics of
    "#include" and mutiple files project.

    Thanks!
    PCHOME, Apr 13, 2005
    #4
  5. PCHOME

    PCHOME Guest

    Darius wrote:


    > extern struct Polytope a_polytope, aa_polytope;
    >
    > in readLP.c
    > #include "readLP.h"
    > struct Polytope a_polytope, aa_polytope;
    >
    > in any other file -------->
    > #include "readLp.h"
    > // optionally you can declare extern struct Polytope a_polytope,
    > aa_polytope;
    > //its your wish as it has already been done when you include readLP.h
    >
    > rest is fine !!!

    Do you mean that #include "readLp.h" is necessary in any other file
    using struct Polytope a_polytope? but "extern struct Polytope
    a_polytope" is optional?
    Thanks!
    Somehow, I do not know why I used to believe that putting the same '
    #include "readLP.h" ' into more than 2 different c files would lead
    mutiple definitions of variables. Now I know it is OK to do so.
    Is it also OK to put 'int test_i = 0;' into that "readLP.h" and
    include it in more than on files?
    I might be wrong,but to me the 'int test_i = 0;' is a declaration puls
    a definition.
    I know it is OK to have 'int test_i;' in it becasue 'int test_i;' is
    just a declararion. How about puting 'int test_i = 0' there? The
    latter is a definition to me(I might be wrong here).

    I looked up several C books before but could not find one clearly
    describe topics about mutiple c files project, #incldue and other
    preprocessor commands, and so on. Do you happen to know which C book
    touch those topics in depth?
    Thanks!
    PCHOME, Apr 13, 2005
    #5
  6. PCHOME

    Darius Guest

    PCHOME wrote:
    > Darius wrote:
    >
    >
    > > extern struct Polytope a_polytope, aa_polytope;
    > >
    > > in readLP.c
    > > #include "readLP.h"
    > > struct Polytope a_polytope, aa_polytope;
    > >
    > > in any other file -------->
    > > #include "readLp.h"
    > > // optionally you can declare extern struct Polytope a_polytope,
    > > aa_polytope;
    > > //its your wish as it has already been done when you include

    readLP.h
    > >
    > > rest is fine !!!

    > Do you mean that #include "readLp.h" is necessary in any other

    file
    > using struct Polytope a_polytope? but "extern struct Polytope
    > a_polytope" is optional?


    yes even this code is valid
    int func()
    {
    extern int a; // for some global variable a;
    extern int a;
    extern int a;
    }

    > Thanks!
    > Somehow, I do not know why I used to believe that putting the same

    '
    > #include "readLP.h" ' into more than 2 different c files would lead
    > mutiple definitions of variables. Now I know it is OK to do so.


    here is a catch; to save yourself from multiple definations

    do this
    <------------------------------readLP.h--------------------------------->

    #ifndef PCHOME_READLP_H
    #define PCHOME_READLP_H

    <-----------here is all the code-------------->

    #endif

    you can use any identifier (a unique string) instead of READLP_H, in
    this way
    when you include that file first time PCHOME_READLP_H is defined and
    next time becoz its already defined, the content is not included again.
    you got it?


    > Is it also OK to put 'int test_i = 0;' into that "readLP.h" and
    > include it in more than on files?


    yes!!!, if you follow the rules above, else you'll get double
    defination error
    but i don't write any defination in .h files. just declare it using
    'extern'

    > I might be wrong,but to me the 'int test_i = 0;' is a declaration

    puls
    > a definition.
    > I know it is OK to have 'int test_i;' in it becasue 'int test_i;' is
    > just a declararion. How about puting 'int test_i = 0' there? The
    > latter is a definition to me(I might be wrong here).


    I think its clear now.

    >
    > I looked up several C books before but could not find one clearly
    > describe topics about mutiple c files project, #incldue and other
    > preprocessor commands, and so on. Do you happen to know which C

    book
    > touch those topics in depth?
    > Thanks!


    kernighan & ritchie and C unleashed (rest you'll learn by experience)

    ---------------
    darius
    Darius, Apr 13, 2005
    #6
    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. orion30
    Replies:
    2
    Views:
    306
    Alf P. Steinbach
    Jul 14, 2003
  2. Bryan Parkoff
    Replies:
    2
    Views:
    6,477
  3. orion30
    Replies:
    1
    Views:
    287
    Barry Schwarz
    Jul 15, 2003
  4. Chris Fogelklou
    Replies:
    36
    Views:
    1,355
    Chris Fogelklou
    Apr 20, 2004
  5. Replies:
    18
    Views:
    7,039
    Karl Heinz Buchegger
    Jul 22, 2005
Loading...

Share This Page