Reputation:
This is the first code:
#include <stdio.h>
#include <stdlib.h>
void test(int,int);
int main()
{
int p=23,f=24;
test(&p,&f);
printf("%d %d\n",p,f);
return 0;
}
void test(int q,int g)
{
q=q+q;
g=g+g;
}
This code generates TYPE MISMATCH ERROR maybe due to the fact that I have passed address of variable as argument during function calling and the formal parameters are not pointers.
This is the second code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int p=23,f=24,q,g;
q=&p;
g=&f;
printf("%d %d\n",q,g);
return 0;
}
The output of second code is
1638220 1638228
In this code, q
and g
are not pointers. So why are they giving correct output, not the error?
Upvotes: 1
Views: 129
Reputation: 76397
Note:
Your comment: "The second code prints the correct addresses of p and f where as first code gives error" is wrong on various levels.
You claim your printf
statement prints the memory addresses of the variables? Wrong, it does no such thing. Can't. Impossible. Not going to happen.
To print the memory addresses of variables, a printf
statement should look like this:
printf("p @ %p\nf @ %p\n", (void *) &p, (void *) &f);//one of few cases where you SHOULD cast
You're printing just a number:
printf("%d %d", p, f);
Those are not the same thing. Just take a look at the example at the bottom of this answer, but read the bit in the middle, too
Well, you declared q
and g
as ints, and assigned them the memory addresses of p
and f
. It's undefined behaviour (ie the standard doesn't determine what to do with this, so it may vary depending on the compiler, WCS: your application crashes). In your case, I'd say this happens:
Basically, a memory address looks something like this:
0x213ABC
A hexadecimal value, which can be interpreted as a number, so there's nothing stopping your from assigning it to a char
, or size_t
or whatever.
HOWEVER, if you compile your code with -Wall
, you should get a warning about the implicit conversion from type int *
to int
. Aside from that, you're "safe". Mind your: the program's output will be unpredictable and therefore rather pointless.
The first snippet contains a bigger problem: you're passing a value to a function that simply does not exist! The test
function cannot handle what you're passing, because its prototype shows it expects 2 ints, not 2 pointers
test(&p,&f);
//to:
test((int) &p,(int) &f);
However, it does compile, as you can see here, however the results are unpredictable (undefined behaviour).
When calling test(&p, &f)
you are calling a function that should look like this:
void test(int *, int *)
However, this signature/prototype is nowhere to be found, so the compiler can't continue. Casting the memory addresses to ints changes all that, and lets the compiler know that the function looks like void test (int, int)
, and that function does exist, hence it compiles.
Think of it like this:
You: What's your phone-number?
Me: abc
you: That's not a phone number
Me: I meant 1-11-111 (number keys for text messages, those were the days)
That's what you're doing here:
test(&p, &f);
//compiler: can't find function test(int *, int *)
//you: I expect you to call test(int, int), and implicitly cast the pointers to ints
That's not how C works.
Note:
As pointed out to me in the coments: Assigning/casting pointer to int is undefined behaviour (ie: the result of these actions are not defined by the standard)
The example program that prints pointers, and unsigned long and ints as they should be printed:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int p = 2, f = 4, q;
q = (int) &f;
printf("p @ %p\nf @ %p\n", (void *) &p, (void *) &f);
//int is too small for 64bit address, use unsigned long here
printf("%d != %ul != %p\n", q, &f, (void *) &f);
return EXIT_SUCCESS;
}
When I ran it through this codepad, I got the following output:
p @ 0xbf70e1d8
f @ 0xbf70e1d4
-1083121196 != 3211846100l != 0xbf70e1d4
Upvotes: 3