I just learned about function pointers (pointers pointing at the adress where where the machine code of a function is stored). This made me think about machine code and how it is stored in memory.
Is the machine code stored consecutively in memory, so that it is possible to "manually" increase the pointer until it points to the following/previous function?
Is this, what a debugger does? He lets me "see" where the program counter is pointing in the machine code?
Conclusion: one can program with function pointers a primitive debugger?
Did I understand this right, or am I way off?
Using a draft C standard that I've managed to track down (N1124), we have similar rules. The section on addition expressions (§6.5.6/2) says that
For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type
And an object type is defined in §6.2.5/1 as
The meaning of a value stored in an object or returned by a function is determined by the type of the expression used to access it. (An identifier declared to be an object is the simplest such expression; the type is specified in the declaration of the identifier.) Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
Since function types are distinct from object types, this suggests that pointer arithmetic on function pointers is prohibited.
In C++, this operation is illegal. The definition of pointer addition, given in §5.7/1, says the following:
For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a pointer to a completely defined object type and the other shall have integral or enumeration type.
However, §3.9/9 states that
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.
Taken together, this means that you cannot increment a function pointer in C++.
Hope this helps!
Kind of. You are assuming functions will be layed out in memory the same way they are in the source code. Most likely, they will not be - the compiler usually moves them around all willy-nilly.
What you could do, however, is step through the code with a pointer to the current instruction, and increment that counter by a certain amount to get to the next instruction. However, in that case we would no longer call it a function pointer, since it's not just pointing to the beginning of a function; instead, we'd call it an instruction pointer.
In fact, this is exactly how a computer works - it has a special register called the program counter which always points to the current instruction, and increments it by a certain amount after every instruction (a GOTO
command is equivalent to writing a value into the program counter).
In the real world, however, this is not how debuggers work - in fact, I'm not even sure if it's possible to have a pointer point to the code-segment in memory in C, other than a function pointer. More likely, you would only need to use this technique if you needed to simulate a program counter, such as writing an emulator for another processor-type.
You can (or at least could) do something like this, but it's decidedly non-trivial. First of all, you can't actually increment or decrement a function pointer -- it points to an address, but pointer math is normally done in increments of sizeof(pointed to type)
-- but with a function, that isn't meaningful, so you can't do math on it.
Most debuggers work (primarily) by using debugging information that relates address to line numbers, function names, variable names, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With