How does C++ process this [duplicate] - c++

This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 7 years ago.
I have here an equation i can't understand how c++ process this. Can someone explain this operation?
code:
#include <stdio.h>
main(){
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int i = 0;
int num = a[i+++a[++i]]+a[++i+i++];
printf("\nnum1: %d i: %d,num,i);
}
why is the answer num = 9 while index i is just equal to 4;

Using ++ twice in the same expression on the same variable is explicitly undefined by all versions of both the C and C++ standards, and so i does not necessarily equal 4. It could be anything at the whim of the compiler writer.
Never do this. Never use ++ and -- twice in the same expression. There is no way to make any statement about what the resultant value will be, and no experience with what it does with one compiler will mean anything with respect to what another compiler does.

Related

C++ weird array behaviour [duplicate]

This question already has answers here:
How dangerous is it to access an array out of bounds?
(12 answers)
indexing past the end of C arrays [duplicate]
(2 answers)
Why doesn't my program crash when I write past the end of an array?
(9 answers)
Array overflow (why does this work?) [duplicate]
(5 answers)
The effects of writing past the end of an array [duplicate]
(5 answers)
Closed 2 years ago.
I was debugging my code for key index counting and found this problem.
I do not understand what is happening here. I've looked at the code for too long to see if I am missing something very obvious, but it does not seem like it.
int main()
{
const int r=7,len=10;
int arr[10]={1,4,6,2,0,4,3,6,5,2};
int count[r+1]={0};
for(int i=0;i<len;i++)
{
count[arr[i]+1]++;
}
cout<<arr[0]<<" ";
for(int i=0;i<r+1;i++)
{
count[i+1]+=count[i];
}
cout<<arr[0]<<" ";
return 0;
}
This is the kind of a mock up code which generates the same bug.
Output:-
1 11
I am not changing value of arr anywhere in my program and still it shows 11 instead of 1 in the output.
if I comment out count[arr[i]+1]++; or count[i+1]+=count[i]; or both it gives the correct output.
1 1
What is happening please explain. (comment if I am doing something silly).
Edit: This is only happening with arr[0].
Compiling it with g++ -Wall -Wextra you get this warning:
rando_so.cpp: In function 'int main()':
rando_so.cpp:15:19: warning: iteration 7 invokes undefined behavior [-Waggressive-loop-optimizations]
count[i+1]+=count[i];
~~~~~~~~~~^~~~~~~~~~
rando_so.cpp:13:18: note: within this loop
for(int i=0;i<r+1;i++)
This hints you to look a bit closer at that second loop. Your variable i goes up to the highest possible index of count - and then you add 1. That is undefined behaviour. In your case, it is likely that you happen to be writing into the first element of arr now, because of how it's laid out on the stack. But as far as I know, anything could happen as a result of this.

Why is int a[0] allowed in c++? [duplicate]

This question already has answers here:
What happens if I define a 0-size array in C/C++?
(8 answers)
Closed 6 years ago.
I find that in the declaration of an array, we cannot specify the size of it like this
int a[0];
I know, empty size array illegal in C++, but In my code, empty size array compiler allowed and give the output.
My code is here :
#include <iostream>
using namespace std;
int main()
{
int a[0];
a[0] = 10;
a[1] = 20;
cout<<a[0]<<endl;
cout<<a[1]<<endl;
return 0;
}
Output:
10
20
Online compiler link : http://code.geeksforgeeks.org/TteOmO
So, My question is, Why is int a[0] allowed GCC compiler?
It issues a warning, for example clang outputs:
warning: zero size arrays are an extension [-Wzero-length-array]
this is undefined behaviour:
a[0] = 10;
a[1] = 20;
Zero length arrays are extensions for gcc, why - you can read on it here:
https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
They are very useful as the last element of a structure that is really a header for a variable-length object:
This is actually C extension but it looks like it also is used in C++, probably to make it easier to use existing structures from C that uses this extension.
Please Look Into This
What happens if I define a 0-size array in C/C++?
If It's a good compiler it will catch that and give a warning.
but with pedantic option compiler can catch it.

Operator ++ with stdout giving unexpected result in C/C++ [duplicate]

This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 7 years ago.
During study in C++ at school, when we learn about operator ++ in C++, we know ++c and c++ are different.
When we test more about this with this kind of code:
#include <iostream>
using namespace std;
int main(){
int c=10;
cout<<++c<<" "<<c++<<endl;
return 0;
}
Why did above code gave output of 12 and 10 in C++?
The computer (we tests with both cout and printf, we also tried VC++ and g++) give this to me:
12 10
Both "cout" and "printf" gave the same result.
But when we test in calculation, the result is all right.
#include <iostream>
using namespace std;
int main(){
int c=10;
int r=++c^c++;
cout<<r<<endl;
return 0;
}
Above source code gave me 0 which means while above XOR operation executing, both left hand side (++c) and right hand side (c++) giving the same value to XOR operator which is 11 (We get the value 11 by replacing c++ with 11 and computer gives the same result 0).
This is really wired. Did anyone noticed this?
By the way, we test in both debug mode and release mode in both Windows and Lubuntu. So we think this is relating to the standard library. But we aren't expecting that we can read the stdlib as a NOOB. So hoping someone can find a reason or solution.
The code int r=++c^c++; is undefined behaviour and should not be used, not ever. You can't modify the variable twice before sequence point.

Indexing an int? How does this work? [duplicate]

This question already has answers here:
Why does i[arr] work as well as arr[i] in C with larger data types?
(5 answers)
Closed 7 years ago.
The following code
#include<stdio.h>
int main()
{
int arr[] = {10,20,30};
cout << -2[arr];
return 0;
}
prints -30. How? Why?
In your case,
cout<<-2[arr];
gets translated as
cout<<-(arr[2]);
because,
array indexing boils down to pointer arithmatic, so, the position of array name and the index value can be interchanged in notation.
The linked answer is in C, but valid for C++ also.
regarding the explicit ()s, you can check about the operator precedence here.
Look at this statement
cout << -2[arr];
First, know that even though it looks strange the following is true
2[arr] == arr[2]
That being said operator[] has higher precedence than -. So you are actually trying to invoke
-(arr[2])
In C and C++, 2[arr] is actually the same thing as arr[2].
Due to operator precedence, -2[arr] as parsed as -(2[arr]). This means that the entire expression evaluates to negating the 3rd element of arr, i.e. -30.

*buf++ = *buf + 10 - Explanation [duplicate]

This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 9 years ago.
Example code
int arr[3] = { 0, 1 };
int* buf = arr;
*buf++ = *buf + 10;
Result of last expression is that buf[0] == 10. I taught it would be buf[0] == 11.
A college of mine wrote something similar to the example code and I taught it works differently than it does. And I would like to know why it works the way it does.
The way I went about figuring it out was to look at the operator precedence table. There it states that suffix ++ has precedence over dereference. Hence I taught that on the left of operator= buf would point to the first element, but on the right of the operator= it would have already been incremented and would point to the second element. However that is not the case.
My question is, why is that so? Preferably a standard quote :) However any explanation is welcome!
You are accessing and modifying the pointer multiple times in a single sequence point. This is undefined behavior.
More generally, reading from and writing to any variable between sequence points is undefined. The fact that you have a pointer in this specific example is by-the-by.
To avoid confusion with the pointer:
int i = 0;
i++ = i + 1; // UB
Logically, should the i on the right hand side be the "current" value of i, or the modified value? This is why it is undefined. Instead, separate the code:
int i = 0;
++i;
i = i + 1;
Which is clear, and well defined.