what is (*vector) ?

Discussion in 'C Programming' started by RocTheEngy, Oct 5, 2005.

  1. RocTheEngy

    RocTheEngy Guest

    Greetings c.l.c...

    I am trying to understand some structure definitions in working code
    (e.g. compiles, runs & produces expected results) that I have. I
    think I've trimmed the code to what is relevant to my question...

    Which is: What is the (*vector) in the "struct function" declaration.
    What is that line doing?

    My best guess is that it is a function definition that returns a struct
    variable * and takes two paramters; an int (argc) and a pointer to a
    struct variable (argv). I'm not quite sure what the (*vector) is ...
    other than the pointer to the function itself?

    Is that the name of the struct [function] member, because I see code
    like fnc_start.vector = null; later in the progam... but i never see it
    assigned to a "real" function address (for fnc_start and fnc_end,
    anyhow) - So I'm skeptical of my understanding...

    Any insight/explaination would be greatly appreciated. Thanks.



    #define MAXVARNAMESIZE 32

    struct variable
    {
    char name[ MAXVARNAMESIZE + 1 ];
    int type;
    char *array;
    size_t array_units;
    struct variable *next;
    };

    struct function
    {
    char name[ MAXVARNAMESIZE + 1 ];
    int arguments;
    int type;
    struct variable * (*vector) ( int argc, struct variable *argv ); /*

    function pointer ? */
    struct function *next;
    };

    extern struct function fnc_start, fnc_end;
     
    RocTheEngy, Oct 5, 2005
    #1
    1. Advertising

  2. RocTheEngy wrote:
    [...]
    > Which is: What is the (*vector) in the "struct function" declaration.
    > What is that line doing?
    >
    > My best guess is that it is a function definition that returns a struct
    > variable * and takes two paramters; an int (argc) and a pointer to a
    > struct variable (argv). I'm not quite sure what the (*vector) is ...
    > other than the pointer to the function itself?

    [...]
    > struct variable * (*vector) ( int argc, struct variable *argv ); /*
    > function pointer ? */

    [...]

    Close. "vector" isn't a function, but rather a pointer to a function,
    with the return type and arguments as you described.

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Oct 5, 2005
    #2
    1. Advertising

  3. RocTheEngy

    Eric Sosman Guest

    RocTheEngy wrote On 10/05/05 16:23,:
    > Greetings c.l.c...
    >
    > I am trying to understand some structure definitions in working code
    > (e.g. compiles, runs & produces expected results) that I have. I
    > think I've trimmed the code to what is relevant to my question...
    >
    > Which is: What is the (*vector) in the "struct function" declaration.
    > What is that line doing?
    >
    > My best guess is that it is a function definition that returns a struct
    > variable * and takes two paramters; an int (argc) and a pointer to a
    > struct variable (argv). I'm not quite sure what the (*vector) is ...
    > other than the pointer to the function itself?


    That's right: the element named `vector' is a pointer.
    It doesn't point to data the way an `int*' or `char*' does;
    instead it can point to a function. If you point it at a
    function of the proper type (that is, at a function that
    takes an `int' and a `struct variable*' as arguments and
    returns a `struct variable*' result), you can use it to
    call that function without actually knowing its name:

    ptr2 = fnc_start.vector(5, ptr1);

    The program might point `vector' to different functions at
    different times (just as a `char*' can point to different
    characters at different times), so the line above might
    call a different actual function each time it's executed.

    > Is that the name of the struct [function] member, because I see code
    > like fnc_start.vector = null; later in the progam... but i never see it
    > assigned to a "real" function address (for fnc_start and fnc_end,
    > anyhow) - So I'm skeptical of my understanding...


    Observe that `null' is not `NULL'. Perhaps there's a
    function named null() somewhere -- given the suggestive name,
    I'd imagine it would be a rather short function, easily
    overlooked.

    > Any insight/explaination would be greatly appreciated. Thanks.
    >
    >
    >
    > #define MAXVARNAMESIZE 32
    >
    > struct variable
    > {
    > char name[ MAXVARNAMESIZE + 1 ];
    > int type;
    > char *array;
    > size_t array_units;
    > struct variable *next;
    > };
    >
    > struct function
    > {
    > char name[ MAXVARNAMESIZE + 1 ];
    > int arguments;
    > int type;
    > struct variable * (*vector) ( int argc, struct variable *argv ); /*
    >
    > function pointer ? */
    > struct function *next;
    > };
    >
    > extern struct function fnc_start, fnc_end;


    It looks like the program intends to set up a linked list
    of these structs, probably with fnc_start at the head and
    fnc_end at the tail. Then (I'd guess) it might insert other
    `struct function' instances at various spots in between them,
    probably with their `vector' elements pointing at assorted
    functions that might be scattered all over the place.

    This sort of thing -- not necessarily with this exact
    data structure -- is often found in "frameworks," where a
    piece of the program controls the execution of other pieces
    it might not even know about when it's compiled. If there's
    a loop in the "framework" that walks along a list of these
    structs and calls all the functions they point to, then a
    previously unknown sub-system can "install" itself by adding
    an appropriate struct to the list. The framework doesn't need
    to know anything about the new sub-system; it just calls
    everything that has been "registered" in the list.

    --
     
    Eric Sosman, Oct 5, 2005
    #3
  4. RocTheEngy

    RocTheEngy Guest

    hope this posts correctly (trying to use the 'correct' google
    instructions found in other threads...)


    Eric Sosman wrote:
    > RocTheEngy wrote On 10/05/05 16:23,:
    > > Greetings c.l.c...
    > >


    [snip]

    > > My best guess is that it is a function definition that returns a struct
    > > variable * and takes two paramters; an int (argc) and a pointer to a
    > > struct variable (argv). I'm not quite sure what the (*vector) is ...
    > > other than the pointer to the function itself?

    >
    > That's right: the element named `vector' is a pointer.
    > It doesn't point to data the way an `int*' or `char*' does;
    > instead it can point to a function. If you point it at a
    > function of the proper type (that is, at a function that
    > takes an `int' and a `struct variable*' as arguments and
    > returns a `struct variable*' result), you can use it to
    > call that function without actually knowing its name:
    >
    > ptr2 = fnc_start.vector(5, ptr1);


    So "vector" also becomes the name of the member to reference... okay
    that's part of my confusion. Clearer.

    > The program might point `vector' to different functions at
    > different times (just as a `char*' can point to different
    > characters at different times), so the line above might
    > call a different actual function each time it's executed.
    >
    > > Is that the name of the struct [function] member, because I see code
    > > like fnc_start.vector = null; later in the progam... but i never see it
    > > assigned to a "real" function address (for fnc_start and fnc_end,
    > > anyhow) - So I'm skeptical of my understanding...

    >
    > Observe that `null' is not `NULL'. Perhaps there's a
    > function named null() somewhere -- given the suggestive name,
    > I'd imagine it would be a rather short function, easily
    > overlooked.


    You're right. I goofed when I searched for the varnames in the code
    and incorrectly wrote "null" when I posted. Your assumption is
    correct, because now that I paid more attention I see:

    fnc_end.vector = fnc_null; /* in a few places */

    /* fnc_null code: */
    struct variable *fnc_null( int argc, struct variable *argv )
    {
    static struct variable nvar;
    static int init = FALSE;

    /* But when is this NOT FALSE? */
    if ( init == FALSE )
    {
    init = TRUE;
    var_make( &nvar, INTEGER ); }

    return &nvar; /* return the address of a local var? */
    /* i have to read up on 'static' i guess... */
    }
    /* end fnc_null code */

    ....

    /* elsewhere in the code */
    f->vector = NULL; /* an example of what I goofed up and you corrected
    */

    ....


    [snip]

    > >
    > > extern struct function fnc_start, fnc_end;

    >
    > It looks like the program intends to set up a linked list
    > of these structs, probably with fnc_start at the head and
    > fnc_end at the tail. Then (I'd guess) it might insert other
    > `struct function' instances at various spots in between them,
    > probably with their `vector' elements pointing at assorted
    > functions that might be scattered all over the place.
    >
    > This sort of thing -- not necessarily with this exact
    > data structure -- is often found in "frameworks," where a
    > piece of the program controls the execution of other pieces
    > it might not even know about when it's compiled. If there's
    > a loop in the "framework" that walks along a list of these
    > structs and calls all the functions they point to, then a
    > previously unknown sub-system can "install" itself by adding
    > an appropriate struct to the list. The framework doesn't need
    > to know anything about the new sub-system; it just calls
    > everything that has been "registered" in the list.


    The code IS an from a language interpreter... and with that
    explanation, I bet you're correct again. Probably, as it reads in the
    "code" it: tokenizes it, formats it into its internal structs, and then
    sets up this data structure to "run" everything once the entire program
    is read in. "Run" would essentailly mean walk the linked list...

    Wow... I've been reading this code for days (wondering what all the
    extra 'overhead' was for) and you picked up on all that from a couple
    struct definitions... Now I can take a different approach to
    understanding what is going on. lmao... NICE!

    Mucho Thanks!
     
    RocTheEngy, Oct 5, 2005
    #4
  5. RocTheEngy

    Eric Sosman Guest

    RocTheEngy wrote On 10/05/05 17:31,:
    > [...]
    > Wow... I've been reading this code for days (wondering what all the
    > extra 'overhead' was for) and you picked up on all that from a couple
    > struct definitions... Now I can take a different approach to
    > understanding what is going on. lmao... NICE!


    I'm expecting to receive the Nobel Prize for Programming
    any day now.

    Seriously, it's not a matter of genius but of experience.
    I've been reading and writing C for almost thirty years, have
    seen lots and lots of gadgetry invented by people smarter
    than I am, and have learned to recognize some recurring
    patterns. Read as much code as you can, learn several different
    programming languages, and become proficient in at least two
    or three; a broader perspective never hurts.

    By the way, not all recurring patterns are good ones.
    But even the Frequently Committed Errors are worth becoming
    familiar with: not only will you improve your ability to spot
    them when debugging somebody else's code, but you'll be more
    likely to avoid them in your own.

    Here's the acid test: Go back and read some code that you
    yourself wrote two or three years earlier. If you can't see
    how to improve it, you've ceased to learn and it's time to
    trim your hair into points. ;-)

    --
     
    Eric Sosman, Oct 5, 2005
    #5
  6. RocTheEngy

    RocTheEngy Guest

    RocTheEngy wrote:
    > hope this posts correctly (trying to use the 'correct' google
    > instructions found in other threads...)
    >
    >
    > Eric Sosman wrote:
    > > RocTheEngy wrote On 10/05/05 16:23,:


    [big snip]

    > > > extern struct function fnc_start, fnc_end;

    > >
    > > It looks like the program intends to set up a linked list
    > > of these structs, probably with fnc_start at the head and
    > > fnc_end at the tail. Then (I'd guess) it might insert other
    > > `struct function' instances at various spots in between them,
    > > probably with their `vector' elements pointing at assorted
    > > functions that might be scattered all over the place.
    > >
    > > This sort of thing -- not necessarily with this exact
    > > data structure -- is often found in "frameworks," where a
    > > piece of the program controls the execution of other pieces
    > > it might not even know about when it's compiled. If there's
    > > a loop in the "framework" that walks along a list of these
    > > structs and calls all the functions they point to, then a
    > > previously unknown sub-system can "install" itself by adding
    > > an appropriate struct to the list. The framework doesn't need
    > > to know anything about the new sub-system; it just calls
    > > everything that has been "registered" in the list.

    >
    > The code IS an from a language interpreter... and with that
    > explanation, I bet you're correct again. Probably, as it reads in the
    > "code" it: tokenizes it, formats it into its internal structs, and then
    > sets up this data structure to "run" everything once the entire program
    > is read in. "Run" would essentailly mean walk the linked list...


    It would not be difficult to store the data structure in a file for
    later retrieval and "execution". It would be a nice feature to add to
    this interpreter... (I realize "something" would have to be done with
    the function pointers when they are retrieved... but I think I can
    handle that).

    Would it be possible to write a "stub" C program and attach the
    datafile created above? I'm not sure how to even research this part...
    My imagination is that another utility would append the datafile
    created above to the end of the "stub" program which contains all the
    relevant function code, and have to 'patch' the stub somehow so it knew
    the offset of where the data begins. The stub program is esentially
    the 'framework' mentioned: it reads itself (from memory or disk?)
    skipping over N
    Code:
     bytes until it arrived at the data structure...
    Then, read in the data structure, populating a linked list, and walk
    the linked list again...  IIRC, flavors of BASIC, REXX and others did
    something like that.
    
    Is there a way/convention to accomplish the above in C without the
    post-compile 'patching' of code in the "stub"?  I know I've way over
    simplified process (possibly totally off-base), so can someone direct
    me to information where I can research this, or do I need to have
    intimate knowledge of compilers, linkers, etc... ?
     
    RocTheEngy, Oct 6, 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. learningjava
    Replies:
    5
    Views:
    2,335
    Miguel De Anda
    Oct 17, 2003
  2. pmatos
    Replies:
    6
    Views:
    24,125
  3. Replies:
    8
    Views:
    1,999
    Csaba
    Feb 18, 2006
  4. Javier
    Replies:
    2
    Views:
    622
    James Kanze
    Sep 4, 2007
  5. Rushikesh Joshi
    Replies:
    0
    Views:
    396
    Rushikesh Joshi
    Jul 10, 2004
Loading...

Share This Page