How are arguments passed to function pointers in C?

jaamit

In the following code snippet Reference, compare is called from main() without any parameters being passed. I assume it is taking ((char *)&key, (char *)string) as the two parameters needed for the function call. But how does it work internally in C? Does the compiler fill in the arguments when compare is called?

#include <search.h>
#include <string.h>
#include <stdio.h>

#define  CNT           2

int compare(const void *arg1,const void *arg2)
{
   return (strncmp(*(char **)arg1, *(char **)arg2, strlen(*(char **)arg1)));
}

int main(void)
{
   char **result;
   char *key = "PATH";
   unsigned int num = CNT;
   char *string[CNT] =  {
      "PATH = d:\\david\\matthew\\heather\\ed\\simon","LIB = PATH\\abc" };

   /* The following statement finds the argument that starts with "PATH"         */

   if ((result = (char **)lfind((char *)&key, (char *)string, &num,
                  sizeof(char *), compare)) != NULL)
      printf("%s found\n", *result);
   else
      printf("PATH not found \n");
   return 0;


}

How do function pointers in C work?

glglgl

compare is called from main() without any parameters being passed.

No. It is just referred to from main.

Essentially, it tells lfind "Hey, if you want to compare entries, take this function - it can be called exactly the way you expect it."

lfind, then, knows about that and whenever it needs to compare two entries, it puts the arguments wherever it would put them on a normal call (on the stack, into the right registers or wherever, depending on the calling conventions of the architecture) and performs the call to the given address. This is called an indirect call and is usually a bit more expensive than a direct call.

Let's switch to a simpler example:

#include <stdio.h>

int add1(int x) {
    return x + 1;
}

int times2(int x) {
    return x * 2;
}

int indirect42(int(*f)(int)) {
    // Call the function we are passed with 42 and return the result.
    return f(42);
}

int indirect0(int(*f)(int)) {
    // Call the function we are passed with 0 and return the result.
    return f(0);
}

int main() {
    printf("%d\n", add1(33));
    printf("%d\n", indirect42(add1));
    printf("%d\n", indirect0(add1));

    printf("%d\n", times2(33));
    printf("%d\n", indirect42(times2));
    printf("%d\n", indirect0(times2));
    return 0;
}

Here, I call the function add1() on my own first, then I tell two other functions to use that function for their own purpose. Then I do the same with another function.

And this works perfectly - both functions are called with 33 by me, then with 42 and with 0. And the results - 34, 43 and 1 for the first and 66, 84 and 0 for the 2nd function - match the expectations.

If we have a look at the x86 assembler output, we see

…
indirect42:
.LFB13:
    .cfi_startproc
    movl    4(%esp), %eax
    movl    $42, 4(%esp)
    jmp *%eax
    .cfi_endproc

The function gets the given function pointer into %eax, then puts the 42 where it is expected and then calls %eax. (Resp., as I activated optimization, it jumps there. The logic remains the same.)

The function doesn't know which function is to be called, but how it is to be called.

indirect0:
.LFB14:
    .cfi_startproc
    movl    4(%esp), %eax
    movl    $0, 4(%esp)
    jmp *%eax
    .cfi_endproc

The function does the same as the other one, but it passes 0 to whatever function it gets.

Then, as it comes to calling all this stuff, we get

    movl    $33, (%esp)
    call    add1
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
    call    printf

Here we have a normal function call.

    movl    $add1, (%esp)
    call    indirect42
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
    call    printf

Here, the address of add1 is pushed to the stack and given to indirect42 so that function can do with it as it wants.

    movl    $add1, (%esp)
    call    indirect0
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
    call    printf

The same with indirect0.

(other stuff snipped as it works the same)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Pointers as function arguments in C

From Dev

Arguments not passed to function in c Kernel

From Dev

How to call a function that has as arguments an array of pointers? in C

From Dev

How to call a function that has as arguments an array of pointers? in C

From Dev

Unable to "point to" passed array of function pointers in C

From Dev

Printing integers passed as arguments in function in C

From Dev

Checking function calls are not passed as arguments (C macros)

From Dev

Printing integers passed as arguments in function in C

From Dev

Arguments passed to function using stack in C

From Dev

Decorators: how arguments are passed to wrapped function?

From Dev

How to check the type of passed arguments to variadic function

From Dev

How to check the type of passed arguments to variadic function

From Dev

How many arguments are passed in a function call?

From Dev

Trouble of pointers as function arguments

From Dev

c++ changing a pointers value that's passed as a function parameter

From Dev

The arguments are not passed into the function correctly

From Dev

how to pass pointers to a function in C

From Dev

Using C++11 smart pointers as C function arguments

From Dev

C++: Vector of function pointers to functions with different type of arguments

From Dev

Objects modified when they are passed to a function as arguments in C++

From Dev

C++ ambiguity in function executor with arguments passed in vector

From Dev

How std::bind increases number of arguments passed to a function?

From Java

How to pass all arguments passed to my bash script to a function of mine?

From Dev

How does one ignore unexpected keyword arguments passed to a function?

From Dev

How to get passed arguments?

From Dev

Giving names to the arguments in function pointers?

From Dev

Catching variables passed to function with no arguments

From Dev

Bash function arguments not passed as expected

From Dev

Access arguments of a function passed as argument

Related Related

  1. 1

    Pointers as function arguments in C

  2. 2

    Arguments not passed to function in c Kernel

  3. 3

    How to call a function that has as arguments an array of pointers? in C

  4. 4

    How to call a function that has as arguments an array of pointers? in C

  5. 5

    Unable to "point to" passed array of function pointers in C

  6. 6

    Printing integers passed as arguments in function in C

  7. 7

    Checking function calls are not passed as arguments (C macros)

  8. 8

    Printing integers passed as arguments in function in C

  9. 9

    Arguments passed to function using stack in C

  10. 10

    Decorators: how arguments are passed to wrapped function?

  11. 11

    How to check the type of passed arguments to variadic function

  12. 12

    How to check the type of passed arguments to variadic function

  13. 13

    How many arguments are passed in a function call?

  14. 14

    Trouble of pointers as function arguments

  15. 15

    c++ changing a pointers value that's passed as a function parameter

  16. 16

    The arguments are not passed into the function correctly

  17. 17

    how to pass pointers to a function in C

  18. 18

    Using C++11 smart pointers as C function arguments

  19. 19

    C++: Vector of function pointers to functions with different type of arguments

  20. 20

    Objects modified when they are passed to a function as arguments in C++

  21. 21

    C++ ambiguity in function executor with arguments passed in vector

  22. 22

    How std::bind increases number of arguments passed to a function?

  23. 23

    How to pass all arguments passed to my bash script to a function of mine?

  24. 24

    How does one ignore unexpected keyword arguments passed to a function?

  25. 25

    How to get passed arguments?

  26. 26

    Giving names to the arguments in function pointers?

  27. 27

    Catching variables passed to function with no arguments

  28. 28

    Bash function arguments not passed as expected

  29. 29

    Access arguments of a function passed as argument

HotTag

Archive