Thread: Casting a type of function to another type of function pointer

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    110

    Casting a type of function to another type of function pointer

    Why does C allow me to cast a function of one type into a function pointer of another type?

    Consider the function:
    Code:
    int product (int* a, int* b){
        return (*a) * (*b);
    }
    C then allows me to compile the following statement:
    Code:
    (void (*) (void*, void*))product;
    That makes no sense whatsoever. Ive cast a function into a function pointer. Can anybody help explain to me what Ive just done by that cast?

    PS: Ive lost my password to old account, my old Username is Vespasian

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The behaviour is probably undefined.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    I also think its undefined. But if I look at K&R example they do something which "looks" like they doing the same undefined action - but I stand corrected. They define two functions which will be used as a parameter to another function:

    Code:
    int numcmp(char *s1, char *s2){
    //do stuff
    }
    Code:
    int strcmp(char *s, char *t){
    //do other stuff...
    }
    The below function is one in which either one of the above 2 functions are pointed to through the use of a function pointer as a fourth argument. Note however that the pointer is void and not of the same type of the functions above - this is so it can accommodate any type of function pointing.

    Code:
    void qsortcustom(/*arg 1*/, /*arg 2*/, /*arg 3*/, int (*comp)(void *, void *)){
    //Do yet more stuff
    }
    Everything up until now makes sense. However:

    Finally, when we call the above function, the code is written like this:
    Code:
    qsortcustom((void**) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ? numcmp : strcmp));
    It makes no sense - numcmp and strcmp are functions and now its been cast to a pointer? So my question is, is the above undefined behaviour? Its in the K&R textbook
    Last edited by Vespasian_2; 03-23-2016 at 07:46 AM.

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by Vespasian_2 View Post
    PS: Ive lost my password to old account, my old Username is Vespasian
    Assuming you still have access to the email account you used to sign up with, you can just reset the password.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Okay, I'll stop being lazy and dig up the actual quote from the standard:
    Quote Originally Posted by C11 Clause 6.3.2.3 Paragraph 8
    A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    So is the K&R quote an example of undefined behaviour? If so, what would be the correct way of doing it? i.e. not making it undefined.

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Vespasian_2 View Post
    It makes no sense - numcmp and strcmp are functions and now its been cast to a pointer?
    The confusion seems to be here. The function names are already pointers (to the start of the function code). They're just being cast to a different kind of pointer.

  8. #8
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    Quote Originally Posted by algorism View Post
    The confusion seems to be here. The function names are already pointers (to the start of the function code). They're just being cast to a different kind of pointer.
    This makes a bit of sense, I think its correct

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Vespasian_2
    So is the K&R quote an example of undefined behaviour?
    Probably not. The undefined behaviour happens "if a converted pointer is used to call a function whose type is not compatible with the referenced type", so presumably this is with reference to say, casting a pointer to a function with 2 arguments to be a pointer to a function with 3 arguments, or where the return/parameter types simply are not compatible. In the case of int (*)(char*, char*) versus int (*)(void*, void*), I would say that they are compatible since a char* can be implicitly converted to a void* and vice versa.

    Quote Originally Posted by algorism
    The function names are already pointers (to the start of the function code). They're just being cast to a different kind of pointer.
    Effectively, though the standard does distinguish between functions and function pointers:
    Quote Originally Posted by C11 Clause 6.3.2.1 Paragraph 4
    A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with pointer type casting
    By Eclipse07 in forum C Programming
    Replies: 14
    Last Post: 12-03-2013, 03:48 PM
  2. Replies: 13
    Last Post: 03-20-2012, 08:29 AM
  3. modf function incompatible pointer type
    By thescratchy in forum C Programming
    Replies: 3
    Last Post: 03-18-2010, 07:46 AM
  4. Pointer type casting
    By vlrk in forum C Programming
    Replies: 2
    Last Post: 08-11-2008, 07:33 AM
  5. pointer type casting
    By RoshanX in forum C++ Programming
    Replies: 1
    Last Post: 03-08-2006, 12:35 PM