--a vs a--, operator precedence [duplicate] - c

This question already has answers here:
What is the difference between ++i and i++?
(20 answers)
Closed 5 years ago.
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
void recursion (int a) {
if (a != 0) {
recursion(--a); //works
recursion(a--); //does not work
printf("%d\n", a);
}
}
int main (int argc, char *argv[]) {
printf("start\n");
recursion(10);
printf("finished\n");
return 0;
}
Why is there a segmentation fault when I recurse (a--) but works fine when I recurse (--a)?
I don't think recursion(a--) is wrong due to undefined behavior because there is only one side effect, which is to decrease a by 1. This side effect is exactly what I wanted. Thanks.

Both --a and a-- have the side effect of incrementing a. The difference is that the value of the expression --a is the value of a after decrementing, while the value of a-- is the value of a before decrementing.
So in the latter case the same value of a is passed recursively to the function. As a result, you have an infinite recursive loop which causes a stack overflow.
You need to use recursion(--a) for the recursive call in order for the decremented value of a to be passed to the function.

Related

C - Output explanation of printf("%d %d\n",k=1,k=3); [duplicate]

This question already has answers here:
Explain the order of evaluation in printf [duplicate]
(5 answers)
Closed 6 years ago.
How to explain the output of the below code:
include <stdio.h>
int main(void) {
int k;
printf("%d %d\n",k=1,k=3);
return 0;
}
Ideone Link
My thinking was that 1 will be assigned to k variable and then 1 would be printed. Similarly 3 will be assigned to k and output will be 3.
Expected Output
1 3
Actual Output
1 1
I am extrapolating from
int a;
if (a = 3) {
...
}
is equal to
if (3) {
...
}
Please let me know where am I going wrong?
The problem is, the order of evaluation of function arguments are not defined, and there's no sequence point between the evaluation or arguments. So, this statement
printf("%d %d\n",k=1,k=3)
invokes undefined behavior, as you're trying to modify the same variable more than once without a sequence point in between.
Once a program invoking UB is run and (if) there's an output, it cannot be justified anyway, the output can be anything.
I expect the reason you're seeing 1 1 is because the two assignment statements are happening control is passed to printf.
printf("%d %d\n",k=1,k=3);
So in response to the down-votes, yes, this this is undefined behavior, and therefore you shouldn't count on this behavior continuing. However, in terms of identifying why the output was 1 1 and not 1 3, we could infer that the assignment of 3 may have been stomped on by a subsequent assignment of 1.
When printf is invoked, the call stack contains two entries containing the final value of k, which is 1.
You can test this out by replacing those with a function that prints something when it executes.
Sample Code:
#include <stdio.h>
int test(int n) {
printf("Test(%d)\n", n);
return n;
}
int main(void) {
int k;
printf("%d %d\n",k=test(1), k=test(3));
return 0;
}
Output:
Test(3)
Test(1)
1 1

Why is the compiler showing warning of following if condition to be always true? [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 7 years ago.
#include<stdio.h>
int main()
{
int a=2;
if(a==3,4)
printf("hello");
return 0;
}
Warning: Condition is always true
Why is it always true??
The , doesn't work like you think it does.
What a , does is evaluate all the expressions that are separated by the , in order, then return the last.
So what your if statement is actually doing is checking a==3 which returns false, but it discards this result. Then it checks if(4), which returns true.
Essentially your code is:
#include<stdio.h>
int main()
{
int a=2;
if(4)
printf("hello");
return 0;
}
a==3,4
should be
a==3.4
Decimal are symbolised with a dot (.) and not a comma(,).
A comma here splits instructions, just as it does in a for statement:
for(int a=0, int b=10 ; b<=0 ; a++,b--)

Explain the output? [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
#include<stdio.h>
int main()
{
int a = 10;
printf("%d %d %d",++a,a++,a--);
return 0;
}
I edited the code a bit..now the outputs are : 11 9 10
It's more complex now..
It's up to the compiler in which order he evaluates the parameters of a function call.
If the compiler goes from left to right (that would explain your output):
a is 10
prä-increment which means a is incremented (the value 11 is passed as parameter)
post-decrement which means a is decremented later (the the value 11 is passed as parameter)
post-increment which means a is incremented later (the value 10 is passed as parameter)
But if I compile this e.g. with another compiler I could get different output.
Rewriting it as follows may make it easier to understand:
NOTE: I have made the assumption that the compiler will produce code to evaluate the parameters from left to right! This may be compiler specific.
#include<stdio.h>
int main()
{
int a = 10;
int param2, param3, param4;
param2 = ++a; // increments a to 11 and evaluates to 11
param3 = a--; // evaluates to current value of a then decrements a (11)
param4 = a++; // evaluates to current value of a then increments a (10)
printf("%d %d %d",param2,param3,param4);
return 0;
}
The place of increment(++) and decrement(--) operator is very important. So in case of ++a the value is incremented from 10 to 11 and then printed, for a-- the current value is printed i.e. 10 and then the a is incremented to 11. Similarly in last case a++ current value 11 is printed and it is incremented to 12.

Passing function parameters and no return statement [duplicate]

This question already has answers here:
Why does flowing off the end of a non-void function without returning a value not produce a compiler error?
(11 answers)
Closed 8 years ago.
#include<stdio.h>
int add(int,int);
main()
{
int a=2,b=3;
printf("%d %d %d",a,b,add(a,b));
getch();
}
int add(int a,int b)
{
int c;
c=a+b;
}
Ok fine this gives me output 2 3 5 ..But for below program
#include<stdio.h>
int add(int,int);
main()
{
int a=2,b=3;
printf("%d %d %d",a,b,add(a,b));
getch();
}
int add(int a,int b)
{
int c;
c=a+b;
c=0;
}
Still it is giving 2 3 5 as output.. as we have no return statement final statement c=0 not initializing .. it should give 2 3 0 but it is giving 2 3 5 only.
It's undefined behavior, anything could happen, you can't rely on it.
Probably what happened is, in the function add(), the value of c is calculated, and left in the stack, in the printf() call, what's in that particular address of stack is printed. Again, you can't rely on undefined behavior.
This is a very good question.
Inside the function add ()
the expression
c=a+b;
is evaluated
In this expression the right hand side has to be evaluated first.
So it returns the value of a+b and that value is stored in your return register and that value is finally stored in c.
In the next expression
c=0;
It is just initialising the value of 0 to c.
It does not need to return any value.
So the value of the return register is still 5.

Decrementing an int while passing multiple copies in the same function call [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Sequence points when calling functions in C and undefined/unspecified behaviour
(2 answers)
Closed 9 years ago.
I am decrementing an integer while passing it to a function. But am seeing some unexpected behavior. I'm new to C, and not sure what to make of it:
#include <stdio.h>
void func(int, int);
int main(){
int i=3;
//func(i--, i); //Prints a=3, b=2
func(i, i--); //Prints a=2, b=3 ??
func(i, --i); //Prints a=2, b=2 ??
}
void func(int a, int b){
printf("a=%d\n", a);
printf("b=%d\n", b);
}
The first call to func works as expected, but what is the deal with the second and third calls?
The order of calculation of function arguments is not specified. E.g. GCC likes to calculate the argument values from right to left. When you have an operator that modifies a variable (or have any other side effect), there must be a sequence point between that operator and any other expression that uses that variable.
This is undefined bahavior, you can't expect either result.
Since parameters passes in a function from right, so in first call where you used post increment operator- it passes the same value (3) and update the value for 'i' left parameter (2).
while in second call, you used pre increment operator which changes itself for right parameter and sends updated values for left parameter.

Resources