Thread: Variable pointers and function pointers

  1. #1
    Imperator of Darkness Luciferek's Avatar
    Join Date
    Jun 2008
    Location
    Detroit, MI
    Posts
    38

    Variable pointers and function pointers

    I started studying pointers and i am becoming confused...
    When you have pointer and that pointer has adress of another variable you need to use * derefrencing operator to access the value that is stored at that adress,
    how come you don't need * operator when using function pointers?
    example with regular pointers
    Code:
    int i(10),c;
    int *b = &i;
    c = *b;
    // Now c is equal to i
    example with function pointers
    Code:
    int IncOne(int var) { 
    
    return ++var; 
    
    } 
    
    int (*inc_one)(int) = &IncOne; 
    result = inc_one(1); 
    // now result is 2;
    Is that right or am I missing something?
    Following the pattern, wouldn't you expect that you have to use * operator to access
    IncOne(int var) function?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, it is one of the "strange" things about C (and thus C++, since it takes after C in most aspects) - you can get the address of a function without & [except if it's a class member function] and use a function pointer without * [whether it points to a member function or not].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Actually, the real syntax is:
    result = (*inc_one)(1);
    But since it's a bit awkward, a new syntax was developed:
    result = inc_one(1);

    This shortcut only works for "normal" function pointers and not for class member pointers:
    Code:
    class A { public: void foo(); };
    int main()
    {
        void (A::* fooptr)() = &A::foo; // Simply A::foo will cause a compile error
        A a;
        (a.*fooptr)(); // OK
        a.*fooptr(); // Error
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    This shortcut only works for "normal" function pointers and not for class member pointers:
    Code:
    class A { public: void foo(); };
    int main()
    {
        void (A::* fooptr)() = &A::foo; // Simply A::foo will cause a compile error
        A a;
        (a.*fooptr)(); // OK
        a.*fooptr(); // Error
    }
    But a.fooptr() would be correct too, as far as I know.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, fooptr() is not a member for A:
    2>g:\w00t\visual studio 2008\projects\temp\temp3.cpp(13) : error C2039: 'fooptr' : is not a member of 'A'
    2> g:\w00t\visual studio 2008\projects\temp\temp3.cpp(7) : see declaration of 'A'
    You have to dereference the pointer, or it won't work.
    Of course, the following syntax also works:

    (&a->*fooptr)();
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Imperator of Darkness Luciferek's Avatar
    Join Date
    Jun 2008
    Location
    Detroit, MI
    Posts
    38
    So in other words, * operator as well as & operator are optional for normal functions and are mandatory for class functions?
    Is * mandatory for class functions? Since a.fooptr(); is wrong?
    Hmm I would understand making the parentheses around *inc_one optional, but operators? Hmm what a strnge language C++ is.
    I would make
    result = *inc_one(1);
    mandatory
    Last edited by Luciferek; 08-01-2008 at 11:09 AM.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Luciferek View Post
    So in other words, * operator as well as & operator are optional for normal functions and are mandatory for class functions?
    Yes.

    Hmm I would understand making the parentheses around *inc_one optional, but operators? Hmm what a strnge language C++ is.
    It's for backwards compatibility for no & before functions and the no need for * for functions is to make it possible to invoke them as if there were functions.
    Both these traits are inherited from C.

    And btw, the paranthesises are mandatory because of operator precedence.

    result = *inc_one(1);

    Basically does

    1) inc_one(1)
    2) *
    3) result = result;

    Therefore, you must force it to dereference the pointer first.

    I would make
    result = *inc_one(1);
    mandatory
    Well, shrug. I wouldn't because I'm quite fond of calling function pointers using function syntax.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Imperator of Darkness Luciferek's Avatar
    Join Date
    Jun 2008
    Location
    Detroit, MI
    Posts
    38
    result = *inc_one(1);

    Basically does

    1) inc_one(1)
    2) *
    3) result = result;
    How does result = result?

    I don't really get operator precedence in this case either;
    if inc_one(1) is a pointer, and pointer is considered a variable
    So it would make more sense to me that * would have higher precedence than a function call
    Bjarne Strostrup really did not impress me here,
    I wonder how backward compatible( read screwed up) will C++oX be!

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Luciferek View Post
    How does result = result?

    I don't really get operator precedence in this case either;
    if inc_one(1) is a pointer, and pointer is considered a variable
    So it would make more sense to me that * would have higher precedence than a function call
    Bjarne Strostrup really did not impress me here,
    I wonder how backward compatible( read screwed up) will C++oX be!
    Elysia means that (variable) result = result (of what just happened).

    The big thorn here is that inc_one(1) is not, in fact, a pointer, since inc_one returns an int. Trying to dereference an int doesn't work.

    Function calls have the highest precedence of everything (well, they're equal to [], ., and ->). If you want to have *inc_one(1) with the * only seeing inc_one, you wouldn't be able to do this either:
    Code:
    foo = -inc_one(1);
    because the - would only see the function name (and who knows what it means to negate a function pointer?) and bad things.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    if inc_one(1) is a pointer, and pointer is considered a variable
    I think the point is that inc_one is the pointer, inc_one(1) is a function call (through a function pointer). And as dereference has lower precedence than grouping, *inc_one(1) should mean dereference the result of calling inc_one with value 1.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Luciferek View Post
    So it would make more sense to me that * would have higher precedence than a function call
    Bjarne Strostrup really did not impress me here,
    That's what you would think, but it's a matter of eye candy and all that.

    I wonder how backward compatible( read screwed up) will C++oX be!
    It won't change much. In the real world, it's a good thing, but unfortunately, I cannot help but to agree to a certain degree with you - some backward compatibility is stupid.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Jul 2003
    Posts
    110
    Even more mind-boggling to me, than being optional, is that you can dereference a function pointer as many times as you want to:

    Code:
    whoie$ cat foo.cc
    int foo() { return 1; }
    int main() {
      int i = (**********foo)();
    }
    whoie$ g++ -c foo.cc
    whoie$
    Look ma! No errors, and quirky grammar! But it isn't Stroustrup's doing, C++ inherited this, along with it's declaration syntax, from C. Blame Ritchie.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  3. Replies: 4
    Last Post: 11-23-2003, 07:15 AM
  4. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM
  5. I need help with passing pointers in function calls
    By vien_mti in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 10:00 AM