confused with address of function in c - c

i am confused! are all of the following printf's the correct way to print the addresses of functions?
Let me tell you my confusion as well. Everytime i run all of these printf's (that is, 1st printf, 2nd printf and 3rd printf), in output i get
02D4
02D4
02D4
but if i remove or comment of 1st and 2nd printf, i get folowing as output
02BA
when i remove third printf statement, i am getting following output
02D0
Again when i uncomment all of these three, i get:
02D4
02D4
02D4
Why is one statement affecting the output of other printf line?
Is this not really the address of function?
I have heard that s and &s give the same value that is address (just like arrays). but here i am confused why s and &s are affected when i try to print b also, where b=s or &s.
#include<stdio.h>
#include<conio.h>
int s(int);
void main()
{
int a=10,*b;
clrscr();
b=s(a++);
b=&s;
printf("%p\n",s); // 1st printf
printf("%p\n",&s); //2nd printf
printf("%p\n",b); //3rd printf
getch();
}
int s(int x)
{
return x;
}

The address of a variable or a function is not something you can depend on, as both the compiler and the operating system can influence where it ends up.
But supposing that the operating system always loads your executable code at the same address, if you change the length of code in the main() function, that may very well influence the starting address of the s() function. Consequently, you get a different result.

Related

What happens when I tell printf to print a variable?

When I run the following code (on Eclipse), I get a pop-up message that the .exe has stop working:
#include <stdio.h>
main ()
{
int x;
x = 1;
printf(x);
}
I know that I should code it as follows in order to make it run:
printf("%d", x);
However, my question is simply what's going on "in there" when I code it the former way.
The printf() first parameter is meant to be a string.
In C, the value '1' is pushed onto the stack to call printf. printf is expecting a string, so it starts to treat 1 as an address.
This causes the "stops working" - when it tries to look at the characters at address 1.
Your code tells printf to print the string at memory address 1.
You probably can't access that, so it crashes.

i try this piece of code in all possible way ,but i cant find why?

Here is the program in C and its output
#include <stdio.h>
#include <conio.h>
void main()
{
int i, t[4], s[4];
for(i=0;i<=3;i++)
{
printf("\n%d",&s[i]);
printf(" %d",&t[i]);
}
for(i=0;i<=3;i++)
{
printf("\n%d %d",&s[i],&t[i]);
}
}
output:
8600 8608
8602 8610
8604 8612
8606 8614
8600 8641
8602 8641
8604 8641
8606 8641
I want to know what exactly happened in second for loop statement that making different from first for loop.
The only obvious problem in your program is that you are passing pointer arguments corresponding to printf's %d format. This is undefined behavior. It can happen to work for some compilation platforms, but you shouldn't count on it.
The most likely explanation is that the ABI for passing pointer arguments to a variadic functions such as printf is, on your platform, different from the ABI for passing int arguments. For all we know, on your platform, pointers are not even the same width as int.
Use the %p format to print a pointer. Or better, use printf("%p", (void*)…);, which is even more portable, in case not all pointer types have the same representation.
The problem is that you are using the wrong format code for printing a pointer. As #PascalCuoq says, you should use %p, not %d.
The reason is that pointers and integers are clearly not the same size, on your system.
When you pass the two pointers to different printf calls %d will print the first part of the pointer value.
When you pass the two pointers to the same printf call, getting the lengths wrong will mean that it will print two different values that do not line up with either pointer.
Your printf statements are printing an integer, put you're putting a pointer (&t[i] means address of the i th element of the t array).
An integer and a pointer are not necessarily the same number of bytes and most implementations of printf takes a fixed number of bytes from the stack for each % field. Also the 'endianism' of the machine will determine whether the least or most significant bit of the address are used as in integer when printf takes its field data from the stack. It looks like you are running on a 16 bit machine with 24 bit addresses and LSB ordering - some kind of micro-controller, I'd guess.
Your arrays are at the memory addresses (converted to hex from your output:
s : 0xC12198
t : 0xC121A0
(24 bit addreses, I think.)
The first loop handles each array seperately in diffierent printf statements, hence you can see the least significant bits of each array incrementing with each iteration.
The second loop tries to handle both arrays in one `printf. So you get values indicating the incrementing part of one of the addresses, plus the second is the most significant part of the address, which is not incrementing, and the second array's address is not output at all.

Why does the strange value come out with an unnecessary % conversion in the code in C language?

I started learning programming only few days ago, so basically I have no knowledge.
I'm starting with C, and I wrote a very simple code which is:
int main (int argc, const char * argv[])
{
printf("%d + %d", 1 + 3);
return 0;
}
with the code above, I got the value of 4 + 1606416608 and later found that the return value is wrong because I put more %d than necessary. Then my question is, how did that strange value actually come out? If anyone knows, please help me. Thank you!!
You know what you did wrong already, so to explain what your particular implementation of C probably did:
When you call printf, a new stack frame is pushed to the call stack. The call stack is a last in first out structure with one 'frame' per called function. So if main called logStuff which called printf then three consecutive frames would be for main, then logStuff, then printf. When printf returns, it's frame is removed from the structure and execution continues with logStuff.
So a frame usually contains at least the parameters passed to the function and storage for local variables. Those things may be one and the same, it's implementation dependant.
With a variadic function like printf there's a stream of unnamed parameters. The bit patterns will be put into an appropriate place in the frame. But C is not a reflective language. Each bit patten doesn't inherently have a meaning: any one could be an integer, a float, or anything else. It also isn't a language that invests in bounds checking. You're trusted to write code that acts correctly.
printf determines the types and number of unnamed parameters from the string. So if you've given it false information, it will interpret the bit patterns with something other than their correct meaning and it may think there are fewer or more than are really there.
You told it there were more. So what probably happened was that the parameters were in the equivalent of an array and it read a value from beyond the end of the array. As it's all implementation dependent, that value may have been meant to represent anything. It could be the address of the caller. It could be uninitialised storage for another local variable. It could be bookkeeping. It could be the format string, incorrectly interpreted as an integer.
What it isn't is any reliable value. It may not even always be safe to read.
You are in undefined behavior land... you are telling a variadic function that you have 2 int sized params, then you only supply one, you are leaking something from the stack.
1) %d is a format specifier, it tells the compiler how you want to access the value stored at a particular location.(here as an integer)
2) For every format specifier you need to provide a corresponding variable or a value, otherwise at runtime you will get "garbage" i.e. some random value.
Example :
int main()
{
int a = 65;
printf("\na = %d", a); // here the value stored in a is accessed as an integer.
printf("\na = %c", a); // the value inside a is accessed as a character.
return 0;
}
In the above example '%d' in the first printf statement tells the compiler that the value stored in the variable a is to be accessed as an integer. (o/p - 65)
In the second printf statement '%c' is used to access the same variable as a character.(o/p - A)
Your code expects two numerical parameters to be printed, and you're giving it one.
Expected:
printf("%d + %d", <some_num>, <another_num>);
You're giving it:
printf("%d + %d", <some_num>);
Where <some_num> is what 1+3 evaluates to. The function expects another argument, but receives garbage instead.
What you should do is
printf("%d + %d = %d", 1, 3, 1+3);

What actually happens when we use %d in printf without passing value to be printed ? The code gives an unexpected output

The following program gives an unexpected output .
#include<stdio.h>
int main()
{
int a=10,b=20;
printf("a=%d",a);
printf(" b=%d");
printf(" %d");
return 0;
}
Why does the above code print:
a=10 b=10 10
The output is same even if I declare b before a, or make 'a' register variable.
According to this post - Behaviour of printf when printing a %d without supplying variable name, a random value from the current stack is printed. But if that was the case, then changing the declaretion styles would result in different results.
So, what is actually happening here?
Function calls are designed so that arguments are always in a pre-defined place. Some older architectures put the arguments on the stack, most new architectures put the arguments in registers.
What's happening here is that the you overwrite the first argument to all the function calls to printf, but the second argument happens to stay unmodified. It's just luck though, anything could have overwritten the place on the stack or the register where the second argument is.
This is the core of undefined behavior in C. Anything could have happened, but usually you can reason about what actually happened. And that's why undefined behavior is so dangerous. Often you end up with behavior that seems predictable and then a minor operating system update or compiler update will change the behavior completely.
put pointer to "a=%d" on the stack, put a on the stack, call printf(), reduce stack-pointer. Then put pointer to " b=%d" on the stack, call printf(), voila, a is still on the stack

Why is printf not equivalent to scanf?

I have a program which displays "hi", but I do not understand why.
I understand both scanf and printf return the number of characters they read/write but how does it work in this case?
void main()
{
if(printf==scanf)
printf("hello");
else
printf("hi");
}
You aren't calling the functions and comparing the results, you are comparing the functions themselves, which boils down to comparing the addresses of the functions (function names will convert to function pointers in many contexts, this is one). What you wrote is equal to this:
/* this is the correct signature for main by the way, not `void main()` */
int main(int argc, char **argv) {
/* compare the address of printf to that of scanf */
if (&printf == &scanf) {
printf("hello");
} else {
printf("hi");
}
}
Since scanf and printf are not the same function they live at a different address so the comparison fails and hi is printed.
Here you compare the adreses of the functions and as the functions are not the same, the equality does not hold. I do not see what confuses you.
You are not calling printf or scanf in the if statement. Rather, you are comparing the location of scanf and printf function in the memory, which are different (otherwise, they will run the same code, and have the same functionality).
You only get back the return value if you invoke the function. An invocation will look like <function_name> ( <arguments separated by commas> ).
As others have already mentioned you are comparing the address of two functions (printf and scanf in this case) and since these functions cannot have the same address, the comparison fails making the program print "hi".
You can try the below code to understand it better
int main(void)
{
printf("printf = %x\n", printf);
printf("scanf = %x\n", scanf);
return 0;
}
Because the address of the function printf is not the same as the function scanf.
Just to add another angle on this matter. Others have already pointed out how you can compare the addresses to the functions. But this code make (well, it's a far stretch) sense:
int main()
{
if(printf("")==scanf(""))
printf("hello");
else
printf("hi");
}
This code is guaranteed to print "hello". Why? Well, lets first look at return values. printf will return the number of characters printed, which is zero for an empty string. scanf will return the number of successful assignments (not the number of characters read), which for an empty string is also zero. Well, if some error occurs, it can also return EOF, which I find highly unlikely even if I cannot guarantee that it will not happen. Well, printf can fail too, and will in that case return an unspecified negative number.
So, it will print "hello", unless both printf and scanf both encounters a problem, AND that printf returns EOF, in which it will print "hi" instead.
However, it could be the case that this is UB. I'm not sure if the order of evaluation is well defined, or even if that matters.

Resources