views:

218

answers:

6

I'm trying to figure out the answer to this question with the following code, but it turns out, the value of the pointer (address of problem3 turned out to be so far away from the parameter and local variables of the function) where the hell is x = problem3; pointing to...

void problem3(int a) {
    int overflowme[16];
    int x = problem3; 
    overflowme[15] = 102;
    printf(" the address of  x is %x\n the addres of the first local is %x\n the addres of the first para is %x\n ", x, &overflowme[15], &a);
}

int main(void) {
    problem3(101);
}

OUTPUT
 the address of  x is 42b613
 the addres of the first local is 12fed8
 the addres of the first para is 12fee4
 Press any key to continue . . .
+4  A: 

problem3 is a pointer to a function. In C, if you use a cast like (int) the compiler basically turns off all type checking and assumes that you know what you are doing (even if, as in this case, it makes no sense) - in this case transforming a pointer to an integer.

Bottom line - don't use casts unless, you really, really need to.

anon
im abit confused...how could problem3 be a pointer? we never declared int* problem3...
and probably truncating address if pointer is greater than int type, e.g. 64-bit platform
aaa
The name of a function is a pointer to that function.
anon
what specifically does pointer points to (the Program Counter, the Frame Pointer, Or the First Parameter [if existed])?
It points to the function. The C Standard does not specify exactly what that means, only that you can use the pointer to call the function.
anon
@metashockwave: `int x = (int) problem3;` does not *call* the function. It "assigns" the function to `x`. More specifically it stores a function pointer, cast to an integer, in x.
Artelius
A: 

First, you're missing a parenthesis in problem3; in order to actually do a function call. Second, assigning x = (int)problem3 assigns the address of the function problem3 to x, cast to an int. This is a perfectly legal thing to do in C, although I'm not sure what you're trying to accomplish.

If you print the address of a function cast to an int, and format it as a hexadecimal number, you will likely print the address of the function as a hexadecimal number. I'm not sure why you are surprised that the number has 7 digits.

JesperE
Question edited to address your first comment - since it was not really germane to the issue under discussion.
Jonathan Leffler
A: 

In the first example, you are assigning the address of your problem3 function to x, and then printing the value of that address.

Casting it to an int is, usually, totally useless. You rarely need to know the actual memory address of a function.

The only time you will want to get the address of a function is when you want to pass it around to some other parts of your code, which will invoke the function (execute it). Check this article for more info on using function pointers.

Groo
+2  A: 

Can you explain why we are allowed to assign x = (int) problem3 in the above code

Because problem3 is a function pointer (i.e. the memory address of a function) and all pointers can be cast to integers.

aren't we assigning "hello world" to x?

No. However you could do that, if you wanted to (by doing x = (int) "hello world";) because "hello world" is also a pointer (a char pointer to be precise), so the above applies.

sepp2k
what happens if we do not typecast problem3 before assignment?
you'd probably get a compiler warning (or error?) like "assignment from pointer to integer without cast"
Graphics Noob
A: 

You're printing addresses of functions ("problem3" and "main"). Those addresses are totally compiler and implementation dependent, so the difference between 6 and 7 digits you're facing.

friol
+1  A: 

Casting (what you're doing when you put (int) in front of something) is magical that way. It will take any sort of thing and turn it into any sort of something else (an int in this case) whether or not it makes any sense at all. You should avoid using casting unless you are absolutely positively sure you have to and there is no other way.

The code for your program exists in memory just like the variables. What is happening here is that the cast is turning the number that represents where in memory the code resides into an integer. That integer can be bigger or smaller depending where in memory the compiler and linker decided to put the code for the function.

Your printf statement does no assignment at all. %x is just a placeholder saying "Take one of the parameters passed to printf and print it out here.". The fact that it's an 'x' has nothing to do with the name of the variable in your program. What the 'x' says is "Print this integer in base 16 (heXadecimal) instead of the normal base 10.". If you put %u or %d in it would still work and you would get out the number represented as an unsigned integer in based 10 or a signed integer in base 10.

Omnifarious