2

Why am I able to assign a function that returns an int with no parameters specified to a function pointer that returns an int but takes an int argument?

For example when I do:

int f()
{ return 0;}

int (*ptr)(int) = f;

the compiler gives me no warnings

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
zero cola
  • 99
  • 1
  • 6
  • See http://stackoverflow.com/questions/188839/function-pointer-cast-to-different-signature – Stéphane Glondu Dec 04 '11 at 00:41
  • Have you considered a C++ compiler to compile your C code? Fixes this problem. – Hans Passant Dec 04 '11 at 00:44
  • Another way to put it, I think, is "if you want that function pointer type to be inconsistent with that definition of `f`, then you could consider writing in C++ instead of C". But just taking your existing C code and trying to compile it as C++ has a number of problems - the rest of your code could fail to compile as C++, or fail to do the same thing in C++ as it did in C, for a host of other reasons, many of which are not bugs in the C code at all. – Steve Jessop Dec 04 '11 at 01:39
  • Not to mention all the cool C99 features that C++ disallows. – Dave Dec 04 '11 at 01:41

2 Answers2

5

In C, f doesn't take "no arguments", but rather "any arguments"*. Say int f(void) to declare "no arguments".

This is different from C++. Notably, C has separate notions of function "declaration" and function "prototype":

int f();              /* declaration -- f is still a mystery */
int f(int, double);   /* prototype -- now we know how to call f */
int f(int n, double c) { return -1; }  /* defintion -- now we can link */

*) As I said in the comment, "any arguments" is restricted to types that do not suffer default-promotion (in the same way as default-promotion happens to variadic arguments). That is, float, all flavours of char and of short int, and also ..., are not permissible in the actual function signature.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • int (*fptr)(char) = f; gives me the warning: warning: initialization from incompatible pointer type, though? – zero cola Dec 04 '11 at 00:42
  • so i take it this is just compiler specific rather than language? – zero cola Dec 04 '11 at 00:48
  • @user1079578: Wait, sorry, my other comment was wrong. You mustn't use types that are default-promotable. That is, `char`, `short int` and `float` are out. Think variadics! – Kerrek SB Dec 04 '11 at 00:49
0

Which compiler do you use?

  • MinGW-GCC-3.4.2: invalid conversion fromint (*)()' to int (*)(int)'
  • Visual Studio 2010 Pro: Error 1 error C2440: 'initializing' : cannot convert from 'int (__cdecl *)(void)' to 'int (__cdecl *)(int)'
kol
  • 27,881
  • 12
  • 83
  • 120