Isn't the size of a function's address known at compilation type ?
-
2@HansPassant OP is asking about function pointers. – interjay Jan 24 '13 at 14:46
-
1What purpose would pointer arithmetic on function pointers have? – netcoder Jan 24 '13 at 15:18
-
A function address is a value held in a function pointer. The size of a function address *is* known at compilation time, `sizeof(void(*)(void))`. And you can do pointer arithmetic with pointers-to-function-pointers. The fact that the size of a function address is known at compile time doesn't help you do pointer arithmetic with pointers-to-functions, though. For another example, the size of a pointer to an incomplete type is also known at compile time, and you can't do pointer arithmetic with pointers to incomplete types either because the size *of the incomplete type* is not known. – Steve Jessop Jan 24 '13 at 15:26
-
You can. It's implemented by GCC and Clang as extension. https://stackoverflow.com/questions/61949561/should-clang-and-gcc-produce-a-diagnostic-message-when-a-program-does-pointer-ar – Tony Tannous May 22 '20 at 07:58
3 Answers
Arithmetic operations on a pointer treats the pointer as an array of objects of a given type. So when you add 3 to an int *
, you advance by three int
s.
Function pointers cannot be interpreted as arrays of anything. Instructions, maybe, or maybe not. Some machines have separate a address space for instructions. Some machines have variable-length instructions.
As an aside, the size of the function is known at compile time, but only after the compiler has finished its work. Compiling the size of a function into itself can be tricky in assembly language, the only sort of programming with any hope of forming such a construct.

- 134,909
- 25
- 265
- 421
-
Even if they could, the size of a function could not be a constant expression because functions can have external linkage. – R.. GitHub STOP HELPING ICE Jan 24 '13 at 14:50
-
Note that I am thinking of interpreting a function as an array of length 1 (which all objects are) of itself. – R.. GitHub STOP HELPING ICE Jan 24 '13 at 14:52
-
1@R.. But two functions of the same type can have different size. Anyway… yuck. – Potatoswatter Jan 24 '13 at 14:53
-
The size of a function might not be known, in particular because it might not make any sense to speak of the size of a function. A compiler might generate code in which two functions share some of the code (e.g., if `foo` and `bar` are identical except `foo` doubles its argument before calculating, the compiler might generate `foo` as instructions that double the argument and jump to `bar`), the code for a function might not be contiguous, some of the constants used by a function might be shared with other functions, a function might be completely inlined and not have any separate code, etc. – Eric Postpischil Jan 24 '13 at 15:00
-
>Some machines have variable-length instructions/separate address space. This makes sense, thanks. >Arithmetic operations on a pointer treats the pointer as an array of objects of a given type I am pretty skeptical here... An array without a defined size is an incomplete type, and arithmetic operations on incomplete type aren't allowed. You could say that the pointer is interpreted as array of size 1, but then I'm not sure why we'd need the pointers in the first place then. – gramm Jan 24 '13 at 15:07
-
"Compiling the size of a function into itself can be tricky". In principle it's not difficult, you would leave an integer-sized space for the value, then go back and fill it in once you've finished doing everything that might affect code size. Whether your assembler actually has a facility to do that is a whole different matter, of course. There might be complications in instruction sets where different immediate values require different-sized instructions, which you could work around by emitting the code for the worst case (e.g. using a constant pool). – Steve Jessop Jan 24 '13 at 15:13
-
1@gramm: you may be sceptical, but it's exactly what the standard says. Addition for pointers is defined in 6.5.6/8 of C11 ("Additive Operators"), and it's defined entirely in terms of arrays of the pointed-to object type. Since there are no arrays of functions, there's no grounds to expect addition of function pointers. – Steve Jessop Jan 24 '13 at 15:16
-
I'm curious as to why anyone would want to do math on function pointers - it has never really occurred to me to do that. I have on occassion used a cast of a function pointer to a "unsigned char *" (which I'm sure is UB as well!) to try to disassemble a function or some such. And at least gcc will store the size of the function - however, it is probably not in a form that is particularly useful for any form of "math" on function pointers. – Mats Petersson Jan 24 '13 at 15:28
-
@Steve: "For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type." You're indeed right. Thanks! – gramm Jan 24 '13 at 16:43
-
@MatsPetersson An interpreter program or JIT might have an array of code segments, and use multiplication as a faster alternative to jump table indirection. – Potatoswatter Jan 25 '13 at 00:44
-
I have certainly written the odd interpreter type program, and used arrays of pointers to functions to do "fast dispatch". A JIT would surely know [keep track of] what it has placed where, and if it wanted to, could place functions at even intervals of X bytes, and do "magical pointer conversion"(tm) [non-portable perhaps, but it's how most system call interfaces work for example - although they tend to be hand-written assembler]. – Mats Petersson Jan 25 '13 at 00:50
-
@R..GitHubSTOPHELPINGICE GCC treats sizeof function as 1. https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html – Tony Tannous May 22 '20 at 08:00
You can only perform arithmetic on related pointers. For example if you have a buffer with multiple pointers into different positions of that buffer, you can perform arithmetic on those pointers. However, if you try to perform pointer arithmetic on two unrelated pointers, like two pointers that point to different buffers, then that is undefined behavior.
A function pointer can not be related to anything except another pointer to the same function.

- 400,186
- 35
- 402
- 621
-
2@JoachimPileborg Not to be pedantic, but you didn't rule out subtracting a function pointer from itself to obtain NULL (or UB), which the standards also don't allow AFAIK. – Potatoswatter Jan 24 '13 at 14:52
-
1@Potatoswatter: pointer subtraction results in an integer, not a pointer, so it certainly doesn't result in null :-). A binary operator that can only be used with equal-valued operands and (when used correctly) always results in `0` would be pretty pointless, I don't think it requires much explaining why it's not provided. Supposing that it existed, all uses of it that don't have UB could be replaced with `((ptrdiff_t)0)`. – Steve Jessop Jan 24 '13 at 15:23
C does not allow or define arithmetic on function pointers. You should have a look here. It is because it will not be defined where you will reach in the code when you do addition and subtraction operation on the function pointers. Just think that you are compiling the same C code for different hardware architectures. When you increment or decrement function pointers they might point to completely different part of code (or instructions as you say) which will be inconsistent across the platforms.