ded@aplvax.UUCP (Don E. Davis) (03/03/86)
In article <857@pucc-j> aaz@pucc-j.UUCP (Marc Mengel) writes: > >char foo[BIGNUM]; >main() >{ > int result; > > /* code to put machine code into foo[] */ > > result = (* (int (*)()) foo)(); >} >-- An interesting corollary to this issue is the following. It doesn't seem to matter if I deference function pointers or not. This seems wrong to me. I feel the y(2) and ((int (*)())x)(3) function invocations should be illegal. #include <stdio.h> main(argc, argv) int argc; char **argv; { int x; int (*y)(); /* y is pointer to function returning int */ int func(); y = func; /* y points to func */ (*y)(1); /* dereference y and invoke func */ y(2); /* DON'T dereference y and invoke func! */ /* the same as above with casting */ x = (int)func; ((int (*)())x)(3); (*(int (*)())x)(4); exit(0); } func(param) int param; { printf("hello %d\n", param); } All of the above appear to be equivalent. What the heck is going on here? -- Don Davis JHU/APL ...decvax!harpo!seismo!umcp-cs!aplcen!aplvax!ded ...rlgvax!cvl!umcp-cs!aplcen!aplvax!ded
chris@umcp-cs.UUCP (Chris Torek) (03/04/86)
In article <196@aplvax.UUCP> ded@aplvax.UUCP (Don E. Davis) writes: >... It doesn't seem to matter if I deference function pointers or not. >This seems wrong to me. ... followed by a code sample including the declaration and call: int (*y)(); ... y(2); The call is wrong. It `just happens' to work in PCC-based compilers. Try compiling the following: main() { int f(), (*p)(); p = f; p(1); (*p)(2); (**p)(3); (****************p)(4); } f(x) int x; { printf("%d\n", x); } Just because it works in your compiler (and in mine) does not mean it is correct.... Of course, the only thing you can do with a pointer to a function is take its address, take its value, or call through it. PCC seems to figure that if you are not doing either of the former, you must be doing the latter, and does not care how many indirections were actually used. While this is a bug in PCC, it does not seem a very important one. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
kwh@bentley.UUCP (KW Heuer) (03/07/86)
In article <44@umcp-cs.UUCP> umcp-cs!chris (Chris Torek) writes: > int f(), (*p)(); > p = f; > p(1); > (*p)(2); > (**p)(3); > (****************p)(4); Although there is no excuse for "p(1)", the other three examples are in fact correct. Recall that there are only two things you can do with a function (not a pointer): call it (as in f()) or take its address (any other use of the name). Thus "p = f" takes the address of function f and stores it in pointer p. Now consider "(**p)(3)". "*p" is of type _function_, but it is not being called (since the next operator is "*" rather than "()"), so we have to take its address. This leaves us with (* pointer_to_function)(3) which is legal. Each time you add a "*" you convert a pointer into a function, but if you don't immediately call it, you are taking its address again. Similarly, you could write "(*exit)(0)". For these reasons I think the address operator should have been required, "p = &f"; as the language stands it is permitted but discouraged (lint warns).