7

Possible Duplicate:
Casting a function pointer to another type

Assume i initialize a function pointer with a function that actually takes less parameters then the function pointer definition, will the function still perform correctly if called through the function pointer?

I tried this with gcc and it worked as expected, but i wonder if that behaviour is consistent across compilers/platforms (i suspect in some enviroments it might wreak havoc on the stack):

#include <stdio.h>

typedef void (*myfun)(int, int, int);

void test_a(int x, int y, int z) {
    printf("test_a %d %d %d\n", x, y, z);
}

void test_b(int x, int y) {
    printf("test_b %d %d\n", x, y);
}

int main() {
    myfun fp;
    fp = test_a;
    fp(1, 2, 3);
    fp = (myfun) test_b;
    fp(4, 5, 6);
}
Community
  • 1
  • 1
Askaga
  • 6,061
  • 5
  • 25
  • 49

4 Answers4

13

It is undefined behavior. Use at your own risk. It has been rumored to cause Nasal Demons!

enter image description here

EvilTeach
  • 28,120
  • 21
  • 85
  • 141
  • This image is awesome. Here I offer a cleaned up version and a vector trace: https://www.dropbox.com/sh/c0f5htyg46jcels/AABD9Qaw2JlhMAKCycAek-9ia?dl=0 – wilx Jan 26 '16 at 01:02
  • 2
    Lol. Thank you. I told the story about undefined behavior to my favorite daughter who likes to doodle. She sent me this the next day. There is simply so much to love about it. – EvilTeach Jan 26 '16 at 01:22
  • Here is the JPG: http://imgur.com/gallery/Zomm1zq/new – wilx Jan 26 '16 at 13:36
6

The behavior of your program is undefined. The fact that it compiles at all is because of the cast, which effectively tells the compiler "this is wrong, but do it anyway". If you remove the cast, you'll get the appropriate error message:

a.c:17:8: error: assignment from incompatible pointer type [-Werror]

(From gcc -Wall -Werror.)

More specifically, the behavior depends on the calling conventions. If you were on a platform were the arguments were passed in "reverse" order on the stack, the program would give a very different result.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 1
    It also may crash if callee clean-up is used. – John Dvorak Nov 18 '12 at 21:37
  • I see. What about defining the function pointer type without parameter list, like ´typedef void (*myfun)()´ . Would the compiler be supposed to guarantee the order of parameters on the stack to be "right" in that case? – Askaga Nov 18 '12 at 21:38
  • @BillAskaga No: to "guarantee" what you want, you may need to ensure that the target function and your function pointer both use the [cdecl calling convention](http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl). – ChrisW Nov 19 '12 at 17:35
3

The function call is undefined behavior.

(C99, 6.3.2.3p8) "[...] If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined."

For information note that a function type:

(C99, 6.2.5p20) "[...] describes a function with specified return type. A function type is characterized by its return type and the number and types of its parameters."

ouah
  • 142,963
  • 15
  • 272
  • 331
2

Whether it works will depend on the calling convention being used.

I wouldn't recommend it.

Khaled.K
  • 5,828
  • 1
  • 33
  • 51
ChrisW
  • 54,973
  • 13
  • 116
  • 224