0

In the following program the function pointer is defined to point to a function which accepts no argument and returns int yet the function pointer works here. Why?

#include<stdio.h>

int mul(int*,int*);

int main()
{   int a=10,b=20;
    int(*p)();
    p=&mul;
    printf("%d ", (*p)(&a,&b));
        return 0;
}


int mul(int*a,int*b)
{   
    return (*a * *b);
}

Vikash
  • 1,109
  • 1
  • 12
  • 19
  • 3
    A function `ret_type name()` doesn't have any limit on number of argument. `ret_type name(void)` is the correct way to declare a function that doesn't take any argument. – nhahtdh Sep 16 '13 at 02:43
  • 1
    "int(*p)()" is not a pointer to a function that returns void. "void(*p)()" is. – abiessu Sep 16 '13 at 02:44
  • Oh I corrected the question. actually the return type is int. Just explain why the function pointer works here. – Vikash Sep 16 '13 at 02:48
  • 1
    `void main()` is wrong. `int main(void)` is correct. (That's not *quite* 100% true; `void main()` might be correct for some embedded systems, but it's 99% certain that that doesn't apply to you.) I'd seriously like to know where you got the idea that `void main()` is valid. It's likely you're using a book written by someone who doesn't know C very well, and I'd like to be able to warn people away from it. – Keith Thompson Sep 16 '13 at 02:53
  • @KeithThompson, superflourous comments are not helpful. – JackCColeman Sep 16 '13 at 03:55
  • @JackCColeman: It's not superfluous. I'm thinking in particular about some C books written by Herbert Schildt, which use `void main()` in examples. The correct definition of `main` is far from the only thing that Schildt has been wrong about. Inattention to detail is a sign of sloppiness that extends well beyond that one point. – Keith Thompson Sep 16 '13 at 05:28
  • @KeithThompson, then talk to Mr. Schildt. When you bring this point up to a newbie it only impedes understanding whatever is actually happening. – JackCColeman Sep 16 '13 at 21:57
  • @JackCColeman: The OP is likely to be using a C book written by an author who does not know the language. `void main()` is a symptom of that problem. I probably should have mentioned that that's not likely to be related to the problem the OP is asking about, but it's still an important point. – Keith Thompson Sep 16 '13 at 22:09
  • @KeithThompson, that's just it, its **NOT** an important point. – JackCColeman Sep 16 '13 at 22:12

1 Answers1

3

In C, int (*p)() means declare a pointer to a function that takes an unspecified number of arguments and return int. Since the number of arguments is unspecified, it is valid to assign pointer to function int mul(int *a, int *b) to variable p.

If you change the declaration to int (*p)(void), which means declaring a pointer to a function that takes no argument and return int, then the compiler is likely to throw a warning about incompatible pointer type. For gcc, a warning is thrown at default level of warning.

As Keith Thompson mentioned in the comment, you should always use prototypes, i.e. declarations that specify the types of the parameters. In this case, it would be:

int (*p)(int*, int*);

Reference

Community
  • 1
  • 1
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
  • 1
    And function declarations with empty parentheses, which don't specify the number of types of parameters, are *obsolescent*. You should always use prototypes, i.e., declarations that specify the types of the parameters. – Keith Thompson Sep 16 '13 at 02:55
  • @KeithThompson: TBH, I don't code anything *properly* in C. If you don't mind, would you please write an answer (or edit my answer) to share the coding practice? – nhahtdh Sep 16 '13 at 02:57
  • I appreciate your answer. – Vikash Sep 16 '13 at 02:58
  • @KeithThompson, I agree with nhahtdh, IF you really understand how to write C code, then you won't make big deals out of nothings. – JackCColeman Sep 16 '13 at 03:59
  • @JackCColeman: What "big deals out of nothings" are you referring to? Do you disagree that one should always use prototypes? – Keith Thompson Sep 16 '13 at 05:26
  • @KeithThompson: I have edited my post to my best understanding of your comment. Is this what you mean? – nhahtdh Sep 16 '13 at 10:50
  • @KeithThompson, use prototypes OR declare functions prior to their usage. (Thus, **always** is too strong of an edict). – JackCColeman Sep 16 '13 at 22:01
  • @JackCColeman: A *definition* that includes the parameter types between the parentheses also provides a prototype. – Keith Thompson Sep 16 '13 at 22:06
  • @KeithThompson, it is my understanding that the common usage of prototype means to code a stub without any program body that allows the compiler to syntax check calls to that program prior to its definition. Now, if you want to call the parameter list for a program a prototype (rather than a parameter list) then I suppose you can, but it still stinks. – JackCColeman Sep 16 '13 at 22:14
  • 1
    @JackCColeman: N1570 6.2.1p2: "A *function prototype* is a declaration of a function that declares the types of its parameters.)". N1570 6.9.1p7: "The declarator in a function definition specifies the name of the function being defined and the identifiers of its parameters. If the declarator includes a parameter type list, the list also specifies the types of all the parameters; such a declarator **also serves as a function prototype** for later calls to the same function in the same translation unit." (I have no idea why you think that "stinks".) – Keith Thompson Sep 16 '13 at 22:35
  • @KeithThompson, because you are being legal as opposed to understanding. For example, what if the declarator does not have a parameter list? The point is to understand how the language works, not have a spec. memorized. For new programmers to read a spec. is useless until they have perspective, and that comes with guidance and experience. – JackCColeman Sep 17 '13 at 02:28
  • 1
    If the declarator doesn't have a parameter list, then it doesn't serve as a prototype. If the function has no parameters, then it *should* be defined with `(void)`, which does serve as a prototype. My point was not about memorizing the spec, I was simply explaining to you what a prototype is. – Keith Thompson Sep 17 '13 at 02:38