Using a function that doesn't exist =\

Discussion in 'C Programming' started by Itay, Mar 23, 2005.

  1. Itay

    Itay Guest

    While going through the code of the open source project PCSX2
    (www.pcsx2.net - PS2 emulator for windows and linux. source code can be
    d/led from here: http://tinyurl.com/6242p), I saw a strange (at least
    for me...) thing:
    in the R5900.h header (hmm..emulating a CPU...), there's a struct which
    looks like this:
    typedef struct {
    int (*Init)();
    void (*Reset)();
    void (*Step)();
    void (*Execute)();
    void (*ExecuteBlock)();
    void (*ExecuteVU0Block)();
    void (*ExecuteVU1Block)();
    void (*EnableVU0micro)(int enable);
    void (*EnableVU1micro)(int enable);
    void (*Clear)(u32 Addr, u32 Size);
    void (*ClearVU0)(u32 Addr, u32 Size);
    void (*ClearVU1)(u32 Addr, u32 Size);
    void (*Shutdown)();
    } R5900cpu;

    and then

    R5900cpu *Cpu;

    and somewhere in R5900.c:

    Cpu->ExecuteBlock();

    ExecuteBlock is not defined anywhere. I did a "search in files" in the
    whole project, and the whole project dir...Only references to
    ExecuteBlock found..no definition. What's going on here?!

    It must be found somehwere, because it's in a function that's - CMIIW -
    always called (indirectly) from WinMain ...and it doesn't make sense
    that it's accidently there...
    Any explanation?

    thanks,

    Itay
     
    Itay, Mar 23, 2005
    #1
    1. Advertising

  2. Itay

    Eric Sosman Guest

    Itay wrote:
    > While going through the code of the open source project PCSX2
    > (www.pcsx2.net - PS2 emulator for windows and linux. source code can be
    > d/led from here: http://tinyurl.com/6242p), I saw a strange (at least
    > for me...) thing:
    > in the R5900.h header (hmm..emulating a CPU...), there's a struct which
    > looks like this:
    > typedef struct {
    > int (*Init)();
    > void (*Reset)();
    > void (*Step)();
    > void (*Execute)();
    > void (*ExecuteBlock)();
    > void (*ExecuteVU0Block)();
    > void (*ExecuteVU1Block)();
    > void (*EnableVU0micro)(int enable);
    > void (*EnableVU1micro)(int enable);
    > void (*Clear)(u32 Addr, u32 Size);
    > void (*ClearVU0)(u32 Addr, u32 Size);
    > void (*ClearVU1)(u32 Addr, u32 Size);
    > void (*Shutdown)();
    > } R5900cpu;
    >
    > and then
    >
    > R5900cpu *Cpu;
    >
    > and somewhere in R5900.c:
    >
    > Cpu->ExecuteBlock();
    >
    > ExecuteBlock is not defined anywhere. I did a "search in files" in the
    > whole project, and the whole project dir...Only references to
    > ExecuteBlock found..no definition. What's going on here?!
    >
    > It must be found somehwere, because it's in a function that's - CMIIW -
    > always called (indirectly) from WinMain ...and it doesn't make sense
    > that it's accidently there...
    > Any explanation?


    The things in the struct are *pointers* to functions,
    not function names. Somewhere you should find something
    like

    void frammis();
    ...
    Cpu->ExecuteBlock = frammis;

    .... and once this has been done, `Cpu->ExecuteBlock()'
    behaves as if you had written `frammis()' instead. What
    you need to do is find the assignment or initialization,
    make note of the name assigned ("frammis"), and then search
    for the function with that name.

    --
     
    Eric Sosman, Mar 25, 2005
    #2
    1. Advertising

  3. Itay

    ItayP Guest

    Can't find it anywhere!
    What's going on here? =\
     
    ItayP, Apr 17, 2005
    #3
  4. Itay

    pete Guest

    ItayP wrote:
    >
    > Can't find it anywhere!
    > What's going on here? =\


    /= ?

    --
    pete
     
    pete, Apr 17, 2005
    #4
  5. Itay

    ItayP Guest

    wtf?
     
    ItayP, Apr 17, 2005
    #5
  6. "ItayP" <> writes:
    > Can't find it anywhere!
    > What's going on here? =\


    Sorry, I have no idea what you're talking about, since you didn't
    provide any context (and my news server doesn't have the parent
    article).

    As we've said here many many times:

    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers."

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 17, 2005
    #6
  7. Itay

    ItayP Guest

    Ok...Sorry for not knowing about the broken reply link.
    I was told that there must be somewhere something similar to that:
    void frammis();
    ...
    Cpu->ExecuteBlock = frammis;
    (shouldn't it be &frammis?)
    anyway, I couldn't find anything similar..


    Itay wrote:
    > While going through the code of the open source project PCSX2
    > (www.pcsx2.net - PS2 emulator for windows and linux. source code can

    be
    > d/led from here: http://tinyurl.com/6242p), I saw a strange (at least


    > for me...) thing:
    > in the R5900.h header (hmm..emulating a CPU...), there's a struct

    which
    > looks like this:
    > typedef struct {
    > int (*Init)();
    > void (*Reset)();
    > void (*Step)();
    > void (*Execute)();
    > void (*ExecuteBlock)();
    > void (*ExecuteVU0Block)();
    > void (*ExecuteVU1Block)();
    > void (*EnableVU0micro)(int enable);
    > void (*EnableVU1micro)(int enable);
    > void (*Clear)(u32 Addr, u32 Size);
    > void (*ClearVU0)(u32 Addr, u32 Size);
    > void (*ClearVU1)(u32 Addr, u32 Size);
    > void (*Shutdown)();
    > } R5900cpu;
    >
    > and then
    >
    > R5900cpu *Cpu;
    >
    > and somewhere in R5900.c:
    >
    > Cpu->ExecuteBlock();
    >
    > ExecuteBlock is not defined anywhere. I did a "search in files" in

    the
    > whole project, and the whole project dir...Only references to
    > ExecuteBlock found..no definition. What's going on here?!
    >
    > It must be found somehwere, because it's in a function that's - CMIIW

    -
    > always called (indirectly) from WinMain ...and it doesn't make sense
    > that it's accidently there...
    > Any explanation?
    >
    > thanks,
    >
    > Itay
     
    ItayP, Apr 17, 2005
    #7
  8. Please don't top-post. Your reply should be after, or interspersed
    with, any quoted text, which should be trimmed to what's necessary for
    context.

    "ItayP" <> writes:
    > Itay wrote:

    [...]
    >> and somewhere in R5900.c:
    >>
    >> Cpu->ExecuteBlock();
    >>
    >> ExecuteBlock is not defined anywhere. I did a "search in files" in
    >> the whole project, and the whole project dir...Only references to
    >> ExecuteBlock found..no definition. What's going on here?!


    [...]

    > Ok...Sorry for not knowing about the broken reply link.
    > I was told that there must be somewhere something similar to that:
    > void frammis();
    > ...
    > Cpu->ExecuteBlock = frammis;
    > (shouldn't it be &frammis?)
    > anyway, I couldn't find anything similar..


    Right. Cpu is a pointer to an object of some struct type. One of the
    members of the struct, a pointer-to-function, is named ExecuteBlock.
    So ExecuteBlock is the name of the struct member, not the name of a
    function.

    If frammis is a function compatible with the declaration of
    ExecuteBlock, then assigning

    Cpu->ExecuteBlock = frammis;

    allows you to call frammis indirectly as:

    Cpu->ExecuteBlock();

    The assignment is the most straightforward way to set the value of
    Cpu->ExecuteBlock, but it's not the only way. I would exect a global
    search for ExecuteBlock to find the assignment unless something ugly
    is being done (like setting it in an assembly language routine,
    perhaps?).

    The assignment does not require the "&" operator. A reference to a
    function name is implicitly converted to a pointer to the function
    (unless it's the operand of a sizeof or "&" operator; in the case of
    sizeof the result is an illegal expression). So you can use &frammis
    if you like, but just frammis is ok.

    Note that a function call is one of the contexts in which a function
    name is implicitly converted to a pointer. A function call is
    effectively an operator whose first operad is a value of an
    appropriate pointer-to-function type, so even an ordinary function
    call:
    myfunc(1, 2);
    is really an indirect call through a pointer. (Of course an
    implementation is free to optimize this to a more direct form in the
    generated code as long as the result is the same.)

    Here's a (rather silly) illustration:

    #include <stdio.h>
    void myfunc(int n)
    {
    printf("myfunc(%d)\n", n);
    }

    int main(void)
    {
    myfunc(1);
    (&myfunc)(2);
    (*&myfunc)(3);
    (*myfunc)(4);
    (**myfunc)(5);
    (***myfunc)(6);
    (*&*&*myfunc)(7);
    return 0;
    }

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 17, 2005
    #8
  9. On 17 Apr 2005 12:24:24 -0700, in comp.lang.c , "ItayP"
    <> wrote:

    >wtf?


    Pete meant "wtf r u babln abt?"

    Or alternatively, post a meaningful question, don't post gibberish


    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
     
    Mark McIntyre, Apr 17, 2005
    #9
  10. Itay

    Old Wolf Guest

    Itay wrote:
    > typedef struct {
    > int (*Init)();
    > void (*Reset)();
    > void (*Step)();
    > void (*Execute)();
    > void (*ExecuteBlock)();
    > void (*ExecuteVU0Block)();
    > void (*ExecuteVU1Block)();
    > void (*EnableVU0micro)(int enable);
    > void (*EnableVU1micro)(int enable);
    > void (*Clear)(u32 Addr, u32 Size);
    > void (*ClearVU0)(u32 Addr, u32 Size);
    > void (*ClearVU1)(u32 Addr, u32 Size);
    > void (*Shutdown)();
    > } R5900cpu;
    >
    > and then
    >
    > R5900cpu *Cpu;
    >
    > and somewhere in R5900.c:
    >
    > Cpu->ExecuteBlock();
    >
    > ExecuteBlock is not defined anywhere. I did a "search in files"
    > in the whole project, and the whole project dir...
    > Only references to ExecuteBlock found..no definition.


    Perhaps it is initialized rather than assigned. If you
    search for 'Cpu' you should see where it's assigned to
    something (obviously you can't write Cpu-> ..... without
    first setting Cpu to point to something).

    For example the code might be something like:

    R5900cpu foo =
    { &foo_Init, &foo_Reset, &foo_Stop, ............ };

    and then

    Cpu = &foo;
    Cpu->Init();
     
    Old Wolf, Apr 17, 2005
    #10
  11. Itay

    Carlos Guest

    Keith Thompson wrote:
    > "ItayP" <> writes:

    [...]
    >>>and somewhere in R5900.c:
    >>>
    >>>Cpu->ExecuteBlock();
    >>>
    >>>ExecuteBlock is not defined anywhere. I did a "search in files" in
    >>>the whole project, and the whole project dir...Only references to
    >>>ExecuteBlock found..no definition. What's going on here?!

    [...]
    > The assignment is the most straightforward way to set the value of
    > Cpu->ExecuteBlock, but it's not the only way. I would exect a global
    > search for ExecuteBlock to find the assignment unless something ugly
    > is being done (like setting it in an assembly language routine,
    > perhaps?).


    Maybe *Cpu was assigned a struct literal?

    --
     
    Carlos, Apr 18, 2005
    #11
  12. Itay

    ItayP Guest

    if (Config.Cpu) Cpu = &intCpu;
    #ifdef __i386__
    else Cpu = &recCpu;
    #endif

    Ahaaa!!! :D

    Keith Thompson wrote:
    > Please don't top-post. Your reply should be after, or interspersed
    > with, any quoted text, which should be trimmed to what's necessary

    for
    > context.
    >
    > "ItayP" <> writes:
    > > Itay wrote:

    > [...]
    > >> and somewhere in R5900.c:
    > >>
    > >> Cpu->ExecuteBlock();
    > >>
    > >> ExecuteBlock is not defined anywhere. I did a "search in files" in
    > >> the whole project, and the whole project dir...Only references to
    > >> ExecuteBlock found..no definition. What's going on here?!

    >
    > [...]
    >
    > > Ok...Sorry for not knowing about the broken reply link.
    > > I was told that there must be somewhere something similar to that:
    > > void frammis();
    > > ...
    > > Cpu->ExecuteBlock = frammis;
    > > (shouldn't it be &frammis?)
    > > anyway, I couldn't find anything similar..

    >
    > Right. Cpu is a pointer to an object of some struct type. One of

    the
    > members of the struct, a pointer-to-function, is named ExecuteBlock.
    > So ExecuteBlock is the name of the struct member, not the name of a
    > function.
    >
    > If frammis is a function compatible with the declaration of
    > ExecuteBlock, then assigning
    >
    > Cpu->ExecuteBlock = frammis;
    >
    > allows you to call frammis indirectly as:
    >
    > Cpu->ExecuteBlock();
    >
    > The assignment is the most straightforward way to set the value of
    > Cpu->ExecuteBlock, but it's not the only way. I would exect a global
    > search for ExecuteBlock to find the assignment unless something ugly
    > is being done (like setting it in an assembly language routine,
    > perhaps?).
    >
    > The assignment does not require the "&" operator. A reference to a
    > function name is implicitly converted to a pointer to the function
    > (unless it's the operand of a sizeof or "&" operator; in the case of
    > sizeof the result is an illegal expression). So you can use &frammis
    > if you like, but just frammis is ok.
    >
    > Note that a function call is one of the contexts in which a function
    > name is implicitly converted to a pointer. A function call is
    > effectively an operator whose first operad is a value of an
    > appropriate pointer-to-function type, so even an ordinary function
    > call:
    > myfunc(1, 2);
    > is really an indirect call through a pointer. (Of course an
    > implementation is free to optimize this to a more direct form in the
    > generated code as long as the result is the same.)
    >
    > Here's a (rather silly) illustration:
    >
    > #include <stdio.h>
    > void myfunc(int n)
    > {
    > printf("myfunc(%d)\n", n);
    > }
    >
    > int main(void)
    > {
    > myfunc(1);
    > (&myfunc)(2);
    > (*&myfunc)(3);
    > (*myfunc)(4);
    > (**myfunc)(5);
    > (***myfunc)(6);
    > (*&*&*myfunc)(7);
    > return 0;
    > }
    >
    > --
    > Keith Thompson (The_Other_Keith)

    <http://www.ghoti.net/~kst>
    > San Diego Supercomputer Center <*>

    <http://users.sdsc.edu/~kst>
    > We must do something. This is something. Therefore, we must do

    this.
     
    ItayP, Apr 21, 2005
    #12
  13. "ItayP" <> writes:
    > if (Config.Cpu) Cpu = &intCpu;
    > #ifdef __i386__
    > else Cpu = &recCpu;
    > #endif
    >
    > Ahaaa!!! :D
    >
    > Keith Thompson wrote:
    >> Please don't top-post. Your reply should be after, or interspersed
    >> with, any quoted text, which should be trimmed to what's necessary
    >> for context.

    [snip]

    Read this again, carefully:

    Please don't top-post. Your reply should be after, or interspersed
    with, any quoted text, which should be trimmed to what's necessary
    for context.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 21, 2005
    #13
    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. H5N1
    Replies:
    1
    Views:
    749
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Apr 12, 2006
  2. Y.S.
    Replies:
    3
    Views:
    1,032
    strajan
    Sep 17, 2003
  3. LT
    Replies:
    7
    Views:
    2,106
    Phlip
    Jul 25, 2004
  4. Mike RegistrationErr

    assert_name doesn't exist as a function?

    Mike RegistrationErr, Apr 20, 2011, in forum: Ruby
    Replies:
    4
    Views:
    122
    Brian Candler
    Apr 20, 2011
  5. Markus Mohr
    Replies:
    7
    Views:
    255
    Thomas 'PointedEars' Lahn
    Nov 28, 2003
Loading...

Share This Page