0

Is the following valid c11 code? I have checked the standard, and it seems unsupported, but I may be missing something. This example is a little contrived, but my actual situation involves like a thousand lines of code and wouldn't make much sense without all that context, and this example correctly isolates the principal I want to ask about. The point is that I use the function's own address by directly using its identifier.

typedef void(*ftype)(void*,void*);

void func(void* v, void* w)
{
   if( func != (ftype)v ) ((ftype)v)( ((void**)w)[0], ((void**)w)[1]) );
}

So, the idea is to run the function pointed to by v for its side effects, with its input given by an array pointed to by w. However, it is desired to not run v if it happens to be a reference to the function 'func'.

EDIT: A comment answered the question: "A direct function call involves an implicit conversion ("decay") from the function name to a pointer to the function. Hence, every recursive function effectively takes its own address."

jack
  • 282
  • 2
  • 9
  • 1
    possible duplicate of [C cast void pointer to function pointer](http://stackoverflow.com/questions/13696918/c-cast-void-pointer-to-function-pointer) – Axalo Apr 17 '15 at 00:21
  • How is this a duplicate of that question? I really don't see any connection. – jack Apr 17 '15 at 00:36
  • 2
    Couldn't you replace the body of the function with `ftype f = func;` and get the same question? – user253751 Apr 17 '15 at 00:37
  • I don't see that as working, I explained in an edit. – jack Apr 17 '15 at 00:38
  • Things take addresses of functions all the time when the function isn't even defined. I fail to see any reason a function couldn't take it's own address. – Mooing Duck Apr 17 '15 at 00:39
  • @Mooing Duck, is there any place in the standard that makes it clear that this sort of think is ok? – jack Apr 17 '15 at 00:41
  • 3
    @jack in C, recursive functions are permitted. A direct function call involves an implicit conversion ("decay") from the function name to a pointer to the function. Hence, every recursive function effectively takes its own address. End of story. – The Paramagnetic Croissant Apr 17 '15 at 00:45
  • @jack: No, there's no place in the standard that says a function can't take it's own address. So the normal rules apply, taking the address of a function is not special. – Mooing Duck Apr 17 '15 at 00:45
  • @Mooing Duck Even if the address is given by use of the function's identifier? I understand that this would be ok if the address was received via argument, but that does not automatically mean that the address can be accessed explicitly through the functions own identifier. But you are saying that this is the case? – jack Apr 17 '15 at 00:58
  • @jack, yes, that's exactly what I and others have repeatedly told you. – Mooing Duck Apr 17 '15 at 01:13
  • @Mooing Duck, only The Paramagnetic Croissant gave a rigorous justification from the standard for using the function's address through its identifier. Other comments either lacked rigor or did not address the specific situation. The fact that behaviour makes sense in context of other behaviour does not imply that such behaviour is defined to be the case. – jack Apr 17 '15 at 01:33
  • @jack we didn't address the specific situation because it's not a special situation. It falls under the normal rules. And there's nothing that says it falls under the normal rules to quote, because it falls under the normal rules. – Mooing Duck Apr 17 '15 at 01:43
  • @Mooing Duck, what I needed was a justification that it did fall under the normal rules. After all, explicitly referencing an address within a function does reference an address of an object in the same piece of code that instructs allocation of memory for that object. That is an inherent difference between receiving its address through an argument at runtime or receiving some other address. The comment I referenced shows that recursive calls basically do what I am asking about, rather than using a specially defined mechanism, which is what shows my desired behaviour is implied by other rules. – jack Apr 17 '15 at 01:49
  • Just a remark, this has nothing to do with the version of C, this always has been so. So the tag [C11] is unnecessary. – Jens Gustedt Apr 17 '15 at 05:48
  • "explicitly referencing an address within a function does reference an address of an object in the same piece of code that instructs allocation of memory for that object." That makes no sense to me. What? Not sure if it's relevant, but according to C, functions are not "objects" and require to instructions to allocate memory. – Mooing Duck Apr 17 '15 at 16:31
  • @Mooing Duck, functions are objects in memory, not in the formal sense the word is used in the C standard, but in the sense that there is a region of memory that stores the instructions comprising a function. A function pointer gives the address of this object. And what I mean by the piece of code that allocates the memory is that the code defining the function is what instructs the compiler to allocate space in the compiled program for the instructions comprising the function, I am not talking about runtime allocation. – jack Apr 18 '15 at 09:22

1 Answers1

1
typedef void(*ftype)(void*,void*);
void func(void* v, void* w);

ftype myfunc = func; //here

Since we can take the address of functions that are 100% undefined in each translation unit, there's no reason that C should have a rule that disallows taking the address of a function that's partially defined. And when we check, there is indeed no such exception. Therefore, you can always take the address of a declared function, even inside the function.

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158