Can you explain what happens with 2019 and what it is? [duplicate] - c

This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 2 years ago.
No compilation and runtime errors
Is 2019 is kind of variable or anything?
Explain this please
#include <stdio.h>
int main()
{
int a, b;
a= b = 2020, 2019;
printf("%d %d", a, b);
return 0;
}

a = b = 2020, 2019;
Is parsed as:
(a = (b = 2020)), 2019;
The , is a comma operator. First the left side of , is executed, it's result is discarded, a sequence point happens and then the right side is executed. So let's execute the left side:
First the inner braces need to be executed, ie. b = 2020 is executed, ie. b is assigned the value of 2020. The simple assignment operator = "returns" the same value that was stored, ie. in this case b = 2020 returns the value 2020. So now we have:
(a = 2020), 2019;
Then a = 2020 is executed - a is assigned the value of 2020. So now we have:
2020, 2019;
The result of the left side of comma operator is ignored (and side effects happen). So now we have:
2019;
It's just a value, something one could call an "empty statement" or "empty expression". A single value doesn't do anything, it is permitted by the language grammar and is like just ignored. Mostly empty statements with a (void) cast are used to remove compilers warnings about unused variables, they are used like int unused; (void)unused; - the (void)unused is just an expression that doesn't do anything.
Can you explain what happens with 2019
Nothing.
and what it is?
A rvalue of type int. A expression that has type int and value 2019.
Is 2019 is kind of variable or anything?
It's not a variable, it's just an expression. Try it out, any number is an expression, like int main() { 1; 2; 3; 1.0; 1 + 1; }

Related

codeblocks gives incorrect result as output

My code :
#include <stdio.h>
int main(){
int a = 5;
int b,c;
if (a==4){
b = 6;
c = 7;
}
printf("%d %d\n",b,c);
}
I know result should be 0 0, but codeblocks giving answer 50 8. I tried online compiler and I got answer 0 0. So what is problem with codeblocks? I am using latest version of codeblocks and gcc c compiler. How can I avoid this kind of problems in future?
The values of b and c variables are garbage because if() condition become false. It means, it is undefined behaviours.
C11 section 6.7.9 Initialization :
Paragraph 10:
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
I know result should be 0 0
Your guess is wrong
The variables b,c are automatic (storage specifier), uninitialized variables -> indeterminate values -> no guarantee on their values -> UB!
In your case you got 50,8 you might as well get other values / print garbage/ crash...
The values for b and c are undefined in this program as they dont get initialised before they get printed
Okay looking at your code and analyzing it step by step,
#include <stdio.h>
int main(){
int a = 5;//You've assigned the value of 5 to integer a.
int b,c;//You've declared two integer variables "b" and "c".
if (a==4)/*Compiler checks whether the if condition is true,which in your case is not*/
{
b = 6;/*Assigning value 6 to the b variable but no effect as the if condition of your's is not satisfied*/
c = 7;/*The same above condition applies here.*/
}
printf("%d %d\n",b,c);/*Here your trying to print the values of b and c,
But remember you have not given them any value. So the compiler automatically prints the garbage value(random value). It need not be 0 all the time.*/
return 0;//You forgot this step btw:)
}

Why a syntax like "a=b--- // a newline, line ends without ;" does not produce syntax error?

What is the output of this program and how?
#include<stdio.h>
int main(){
int a=0,b=10;
a=b---
printf("the value of b=%d",b);
printf("the value of a=%d",a);
return 0;
}
In your code, writing
a=b---
printf("the value of b=%d",b);
is same as
a = b---printf("the value of b=%d",b);
which is an expression with undefined behavior, as an attempt is made to change and use the value of variable b in two subexpressions without a sequence point in between. Hence, the output of this code cannot be justified.
Without the above problem, in general, the syntax is similar to
x = (y--) - (<return value of printf() call>)
which is a perfectly valid syntax.
Note:
Why a = b---<something> is treated as a = (b--) - <something> and not a = b - -- <something> is due to the maximal munch rule.
Strictly speaking, as others have said since this is undefined behaviour, the result could be anything . And while they're right, it doesn't explain why you get this specific answer in this specific compiler.
In practice b will usually be printed as 9, or 10 depending on whether the compiler does the decrememnt first or the printf first.
printf returns the number of characters printed. Which I think is 16 or 17 in this case.
So this is like writing a = (b--) - 16; b is 10 before the decrement and it's a post decrement so this is the value used.

Interpretation of instructions without effect

How can we interpret the following program and its success?(Its obvious that there must not be any error message). I mean how does compiler interpret lines 2 and 3 inside main?
#include <stdio.h>
int main()
{
int a,b;
a; //(2)
b; //(3)
return 0;
}
Your
a;
is just an expression statement. As always in C, the full expression in expression statement is evaluated and its result is immediately discarded.
For example, this
a = 2 + 3;
is an expression statement containing full expression a = 2 + 3. That expression evaluates to 5 and also has a side-effect of writing 5 into a. The result is evaluated and discarded.
Expression statement
a;
is treated in the same way, except that is has no side-effects. Since you forgot to initialize your variables, evaluation of the above expression can formally lead to undefined behavior.
Obviously, practical compilers will simply skip such expression statements entirely, since they have no observable behavior.
That's why you should use some compilation warning flags!
-Wall would trigger a "statement with no effect" warning.
If you want to see what the compilation produces, compile using -S.
Try it with your code, with/without -O (optimization) flag...
This is just like you try something like this:
#include <stdio.h>
int main(void){
1;
2;
return 0;
}
As we can see we have here two expressions followed by semicolon (1; and 2;). It is a well formed statement according to the rules of the language.
There is nothing wrong with it, it is just useless.
But if you try to use though statements (a or b) the behavior will be undefined.
Of course that, the compiler will interpret it as a statement with no effect
L.E:
If you run this:
#include <stdio.h>
int main(void){
int a;
int b;
printf("A = %d\n",a);
printf("B = %d\n",b);
if (a < b){
printf("TRUE");
}else{
printf("FALSE");
}
return 0;
}
You wil get:
A = 0
B = 0
FALSE
Because a and b are set to 0;
Sentences in C wich are not control structures (if, switch, for, while, do while) or control statements (break, continue, goto, return) are expressions.
Every expression has a resulting value.
An expression is evaluated for its side effects (change the value of an object, write a file, read volatile objects, and functions doing some of these things).
The final result of such an expression is always discarded.
For example, the function printf() returns an int value, that in general is not used. However this value is produced, and then discarded.
However the function printf() produces side effects, so it has to be processed.
If a sentence has no side effects, then the compiler is free to discard it at all.
I think that for a compiler will not be so hard to check if a sentence has not any side effects. So, what you can expect in this case is that the compiler will choose to do nothing.
Moreover, this will not affect the observable behaviour of the program, so there is no difference in what is obtained in the resulting execution of the program. However, of course, the program will run faster if any computation is ignored at all by the compiler.
Also, note that in some cases the floating point environment can set flags, which are considered side-effects.
The Standard C (C11) says, as part of paragraph 5.1.2.3p.4:
An actual implementation need not evaluate part of an expression if it
can deduce that its value is not used and that no needed side effects
are produced [...]
CONCLUSION: One has to read the documentation of the particular compiler that oneself is using.

Invalid output in `int` array

I am trying to learn pointers and I just encountered a situation I do not understand.
int main()
{
int num[3][2]={3,6,9,12,15,18};
printf("%d %d",*(num+1)[1],**(num+2));
}
As per what I have learnt the output should be :
12 15
but actually it is:
15 15
Why? Please clarify as to how things are calculated here as what I think is first *(num+1) get calculated and point to the 1st one i.e. {9,12} and then [1] should dereference to first element i.e 12.
I am using GCC compiler.
In your data,
int num[3][2]={3,6,9,12,15,18};
equivalent to:
int num[3][2]={{3,6},{9,12},{15,18}};
i.e.
num[0][0] = 3
num[0][1] = 6
num[1][0] = 9
num[1][1] = 12
num[2][0] = 15
num[2][1] = 18
thus,
*(num+1)[1]
= *(*(num+1+1))
= num[2][0]
=15
and,
**(num+2))
= num[2][0]
=15
Array subscript [] operator has higher precedence than dereference operator *.
This means the expression *(num+1)[1] is equivalent to *((num+1)[1])
And if we take it apart
*(*((num+1)+1))
*(*(num+2))
*(num[2])
num[2][0]
See C Operator Precedence, [] is processed before *
That means
(num+1)[1]
*((num+1)+1)
*(num+2)
Together with the additional * (not written in my example),
it becomes the same as the second thing.

Combined preincrement and postincrement in C

This is an ugly code used only to terrorize job applicants during interviews...
But I cannot understand the logic behind it.
Can someone explain why the expression with "b" is not equal to the one with "a"?
#include <stdio.h>
void main(){
int a = 1, b = 1, c = 1;
printf("%d %d %d", ++a + a++ + 1, 1 + ++b + b++, ++c + c++); // displays 6 5 5
}
Thank you very much.
Read up on Undefined behavior and sequence points.
This is a slightly different, yet similar example (thanks Zan):
2) Furthermore, the prior value shall be accessed only to determine the value to be stored.
C++ example:
std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2
The logic is simple:
Create Undefined Behavior and let the nasal demons terrorise the job applicant. That is known as job security.
If you write to a variable, you must not access it again without intervening sequence point except to calculate the value which shall be written.
There's a second case of UB or at least Implementation Defined Behavior:
void main()
Should be one of
int main(void)
int main(int argc, char* argv[])
Just to prove that this is a terrible idea, here's the output in VS2012 (technically C++ compiler I suppose):
5 5 4
GCC & G++:
6 5 5
So apparently your interviewer tried it in GCC.

Resources