While writing some code, I came across a problem where values I set were being set wrong. I eventually found the culprit line and while testing around found that it behaved differently on C++14 and C++17. The code is as follows:
#include <stdio.h> #include <cstdint> #include <cstring> int main() { uint8_t *p = new uint8_t[3]; memset(p, 0x00, 1); p++; memset(p, 0xF0, 1); p++; memset(p, 0xFF, 1); p--; p--; // This line in particular *p++ = *p; *p++ = 0x0F; p--; p--; printf("Position 0 has value %u\n", *p); p++; printf("Position 1 has value %u\n", *p); p++; printf("Position 2 has value %u\n", *p); return 0; }
On C++14 it prints:
Position 0 has value 240 Position 1 has value 15 Position 2 has value 255
And on C++17 it prints:
Position 0 has value 0 Position 1 has value 15 Position 2 has value 255
I'm curious why it acts differently on different C++ versions. It looks as though on C++14 the *p
right side of the assignment is evaluated after the ++
. Did this change? And if the ++
has precedence, why does it not happen before the dereference on the left side of the assignment operator?
C++14 is a version of the ISO/IEC 14882 standard for the C++ programming language. It is intended to be a small extension over C++11, featuring mainly bug fixes and small improvements, and was replaced by C++17. Its approval was announced on August 18, 2014. C++14 was published as ISO/IEC 14882:2014 in December 2014.
The major difference between C and C++ is that C is a procedural programming language and does not support classes and objects , while C++ is a combination of both procedural and object oriented programming language ; therefore C++ can be called a hybrid language.
I'd use the C++17 flag by default, it's the default in the latest version of clang too iirc. You should use the latest language features as long as you don't need to support builds on older compilers or embedded platforms that only have outdated compilers, as mentioned above.
Reading from and writing to the variable (via the post-increment) used to have undefined behaviour, because the =
did not introduce a sequence point. You could have received either behaviour (or none, or explosions) in C++14.
Now, there is a sequencing order defined for this case and your C++17 results are reliable.
Although it's still bad, unclear code that should not be written!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With