I wrote this simple c program and I got some strange results that I don't understand (results are described in the line comments)
int arr[3] {1, 2, 3};
int* p{ nullptr };
p = arr;
std::cout << p[0] << " " << p[1] << " " << p[2]; // prints 1 2 3, OK
p = arr;
std::cout << *(p ) << " " << *(p ) << " " << *(p); // prints 2 1 3 ??
p = arr;
std::cout << *p << " " << *( p) << " " << *( p); // prints 3 3 3 ??
p = arr;
std::cout << *p << " "; p;
std::cout << *p << " "; p;
std::cout << *p; // prints 1 2 3, OK
it seems that the pointer increments along a std::cout concatenation don't work. What's wrong in my idea? I supposed it should have worked. best
final edit: I was using c 14, I switched to c 20 and now it works properly thank you everybody!
CodePudding user response:
int* p{ nullptr }; std::cout << p[0] << " " << p[1] << " " << p[2];
This is Undefined Behavior, as you are dereferencing nullptr
, p
does not point at valid memory yet.
p = arr; std::cout << p[0] << " " << p[1] << " " << p[2];
This is well-defined behavior. p
points at valid memory, is always incremented before dereferenced, and is incremented in a deterministic and valid manner. This is the same as if you had written the following instead:
std::cout << *(p 0) << " " << *(p 1) << " " << *(p 2);
p = arr; std::cout << *(p ) << " " << *(p ) << " " << *(p); p = arr; std::cout << *p << " " << *( p) << " " << *( p);
Both of these are Undefined Behavior prior to C 17, because the order in which chained operator<<
calls are evaluated is not guaranteed in earlier versions, the compiler is free to evaluate them in whatever order it wants. This is no longer the case in C 17 onward.
p = arr; std::cout << *p << " "; p; std::cout << *p << " "; p; std::cout << *p;
This is well-defined behavior. p
points at valid memory, is always dereferenced before incremented, and is incremented in a deterministic and valid manner.