Why is array indexing symmetric in index and name [duplicate] - c++

This question already has answers here:
With arrays, why is it the case that a[5] == 5[a]?
(20 answers)
Closed 6 years ago.
Looking at some weird obfuscation contest code today I realized that array indexing is symmetric, in other words, x[n] is the same as n[x]. For example, consider the code below:
#include <iostream>
int main()
{
int x[] = {0, 1, 2, 3, 4};
std::cout << x[3] << ' ' << 3[x]; // both display 3
}
Live on Coliru
Is this indeed standard compliant, and if yes, is there any good reason why? And a bonus if you can provide a standard reference/quote.
PS: the code compiles fine with both gcc and clang

The reason is that in C (and C++) both expressions are equal to *(x + 3) == *(3 + x).

Related

How is the following character array accessed [duplicate]

This question already has answers here:
C++ array[index] vs index[array] [duplicate]
(4 answers)
With arrays, why is it the case that a[5] == 5[a]?
(20 answers)
Accessing arrays by index[array] in C and C++
(2 answers)
Closed 4 days ago.
#include <iostream>
using namespace std;
int main()
{
char str[]="ABCD";
for(int i=0;str[i]!='\0';i++)
{
cout<<i[str]<<" ";
}
return 0;
}
The output of the following code is A B C D but i am not able to understand how we are accessing the array
Let's consider str has address 100 (Very simplified example).
It has 5 chars in it, so the addressed are 100, 101, 102, 103, 104, where in the 104 is '\0'
When you try to access str[i], it actually calculates the address str + i, and gets the value: *(str + i). And when you try to write the reversed way i[str], it also calculates the address i + str. So you get correct result.
Note that here is working pointer arithmetic (so for every type T you get the address pointer + sizeof(T))
And your
for(int i=0;str[i]!='\0';i++)
{
cout<<i[str]<<" ";
}
Will access addresses 100, 101, 102, 103, 104. And print the right values.

why does the output change when i change z -1 to z--? [duplicate]

This question already has answers here:
Pre vs Post Increment
(3 answers)
Closed 8 months ago.
I have the following c++ program:
#include <iostream>
using namespace std;
//looping through arrays backwards
int main() {
int a[3] {1, 2, 3};
int x = sizeof(a), y = sizeof(int), z = x / y;
for(int i = z - 1; i >= 0; i--) {
cout << a[i] << " ";
}
return 0;
}
And it outputs 3 2 1. But if I change the first parameter in the for loop to int i = z--;, it outpus 2 3 2 1 and I don't understand why. Aren't z - 1 and z-- supposed to be the same thing? Could someone please explain why? Also, I'm a begginer in C++ and I'm learning via the W3Schools tutorial about it. Thanks!
The expression z-- evaluates to z, then - as a side effect - z is decremented (scheduled according to scheduling rules). This means, you're essentially saying int i = z in your loop (and then decrement z, but it's not used anymore) - therefore, your code has UB. The 2 printed is purely coincidental, anything might be printed or anything could happen in your code. If you'd like to use --, use it as prefix, i. e., int i = --z.

Why C array has extra bytes at tail? [duplicate]

This question already has answers here:
What is the purpose of allocating a specific amount of memory for arrays in C++?
(5 answers)
Closed 5 years ago.
I examine that C array maybe have some extra bytes at tail.
There are my code
int a = 5;
int test[] = {1,2,3,4};
int b = 5;
test[-1] = 11;
test[4] = 11;
cout << b << endl; // 11
cout << a << endl; // 5
You can see the running result there
the value of b is changed through changing test[-1]'s value. But when I change test[4]'s value, the value of a doesn't change;
I use gdb to check their addresses, found that
In g++ 6.4.0, the address of a substract address of test[4] is 8 bytes
In clang++ 3.8.1, the address of a substract address of test[4] is 4 bytes
So, I am curious that why the array has some bytes at tail?
Thanks #Peter A.Schneider to explaining the question.
It is surely a UB , But it is just a experimental code. This isn't a discuss for practical code.
generally,variables at the runtime stack are close together. b is close to test, but why 'a' is not close to 'test+3'. That's the key of the problem.
test[-1] = 11;
test[4] = 11;
This is undefined behavior.(Meaning anything could have happened). In your case you changed the value of b because they are adjacent in the memory where they are allocated. But you shouldn't rely on it. Because this may blow up your program or results in erroneous code behavior most of the time.
The UB you have is because `Accessing an array index out of bound in undefined behavior."

C++ for loop and do-while loop of a single dimensional array gives questionable output [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am taking a course on edx.org Introduction to C++ by Microsoft. I get unwanted output when looping through a single dimensional array. The code is below.
<#include <iostream>
int main() {
int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 1; arrayName[i] <= 20; i++) {
std::cout << i << std::endl;
}
The output of this is:
1
2
3
4
5
6
7
8
9
10
11
Where does the 11 come from? And, if I make i=0, it also prints a 0. How does it print more than 10? And, when I try to change arrayName[10] to arrayName[9], I get a compiler error that there are too many initialized values:
int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };
do {
std::cout << i << std::endl;
i++;
} while (arrayName[i] < 5);
The output is:
12
13
14
15
16
17
18
That do-while loop outputs 7 integers that I did not specify to be included in the arrayName[] array.
I don't know what I am doing wrong or what I am not understanding.
Please help. Thank you!
First, note that arrays in c++ start at index 0. So in int arrayName[3] = {10, 42, 88}; then arrayName[1] is 42, not 10. That means the last element in this array is int arrayName[2]. There is no element at index 3.
Your array only contains 10 elements (indices 0 to 9). The standard does not specify what happens when you access an element past the end of an array, anything can happen. In your case, arrayName[10] and arrayName[11] happens to give you something less than or equal to 20, and then arrayName[12] gave you something greater than 20, ending the loop. If you try it on another computer, or even at a different time, the results will vary. It might also crash (this is the best case scenario).
See this answer for more information on undefined behavior.
I finally found this: Correct way of loop through the C++ arrays, answer by https://stackoverflow.com/users/1619294/mark-garcia.
Changed my code to:
std::cout << "Looping through arrayName3 with std::array and letting the compiler determine how many objects to print:" << std::endl;
// Need to #include <array>
std::array<int, 10> arrayName3 = { 1,2,3,4,5,6,7,8,9,10 };
for (const auto& i : arrayName3) // Range-for
{
std::cout << i << std::endl;
}
The output was what I wanted:
1
2
3
4
5
6
7
8
9
10
This let's the compiler know it is deciding what to output. It would be great to know how to change this to control how many indices to loop through.

Compiler issue or some bug in code block of c [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
order of evaluation of operands
(6 answers)
Closed 9 years ago.
The very amazing and shocking logical problem occur which simple coding in c++.
See the following two chunk of code.
code 1
int m = 5, n = 0;
n = m++ * ++m;
//This print m = 7 and n = 36
//Which is logically wrong
code 2
int m = 5;
int n = m++ * ++m;
//This print m = 7 and n = 35
//Which is logically right
As we think logically the code block 2 gives right answer, but the amazing or magic thing is that what is wrong with code block1?
As part code its same, just we declared int n earlier.
May be some compile!!!!!!
Check http://en.cppreference.com/w/cpp/language/eval_order especially the part which discusses "Undefined behavior". Basically it's not a bug in the compiler. The language says what you're doing is undefined.
Besides the "undefined behavior" part, which is important, there's nothing illogical here. Assuming the evaluation is from right to left:
++m -> value is 6, m is 6
m++ -> value is 6, m is 7
6*6 = 36