Undefined Behaviour in C++ [duplicate] - c++

This question already has answers here:
Program behaving strangely on online IDEs
(4 answers)
Closed 3 years ago.
I got this from a facebook post. What's happening here? See the output in ideone. Output is more than 10 lines.
Code:
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; ++i)
cout << i*1000000000 << endl;
}
Ideone Link

Your platform most likely has a 32 bit int. So 1'000'000'000 is an int, and the compiler will attempt to evaluate i * 1'000'000'000 as an int too. This results in an overflow from i being 3 onwards.
The behaviour on overflowing a signed integral type is undefined.
Note that this makes the entire program behaviour undefined, which accounts for the multiple lines of output (beyond 10) that you observe.
(If you had chosen 10'000'000'000 say instead then the multiplication would have been evaluated with long long types and the behaviour would be well-defined!)

Related

Why is unsigned left bit shift overflow different between runtime and compile time? [duplicate]

This question already has answers here:
Why doesn't left bit-shift, "<<", for 32-bit integers work as expected when used more than 32 times?
(10 answers)
Unexpected C/C++ bitwise shift operators outcome
(6 answers)
Why the output of `printf("%llu\n", 1ull << n);` and `printf("%llu\n", 1ull << 64);` is different in C++? (n=64) [duplicate]
(3 answers)
Is right-shifting an unsigned integer by its total number of bits UB ? [duplicate]
(1 answer)
Closed 23 days ago.
I have the following code in C++
#include <iostream>
using namespace std;
int main(){
unsigned long long a;
cin>>a;
cout<< (1ull<<64ull) << ' ' << (1ull<<a) << endl;
}
now inputting 64, the output is
0 1
In short, the compiler seems to use a circular shift at runtime. But from my reading of the relevant cppreference page, I think it's supposed to be normal modular arithmetic, so the bit should just disappear as in the compile-time version. I tested this on GCC 11, GCC 12 and clang 14 so it's extra unlikely to be a compiler bug. So what am I missing here?
from the quoted cppreference page
In any case, if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.
since 64 is the number of bits in unsigned long long on my machine, this is undefined behavior

64-bit Multiplication Overflow Gets 0 in C++ [duplicate]

This question already has answers here:
Why is unsigned integer overflow defined behavior but signed integer overflow isn't?
(6 answers)
Is signed integer overflow still undefined behavior in C++?
(3 answers)
Why is the phrase: "undefined behavior means the compiler can do anything it wants" true?
(2 answers)
Closed 3 months ago.
Firstly, I defined two bit integers, and multiply them. The answer must overflow, and I got a negative number. Then, I defined two 64-bit integers, and multiply them. The answer must overflow, and I expected to get a negative number. But, the result was zero. I don't know why this happen, could anybody give me some help?
The code is below.
#include <iostream>
int main ()
{
int x = 1e9, y = 1e9;
printf("%d\n", x * y);
int64_t a = 36028797018963968;
int64_t b = 36028797018963968;
printf("%ld\n", a * b);
return 0;
}
The result is below.
ubuntu#VM-0-2-ubuntu:~/Projects/Test$ g++ test.cpp -o a
ubuntu#VM-0-2-ubuntu:~/Projects/Test$ ./a
-1486618624
0

Why does my for loop not stop when I use an int32_t loop variable? [duplicate]

This question already has answers here:
Why is this loop being endless?
(3 answers)
Is signed integer overflow still undefined behavior in C++?
(3 answers)
Why does integer overflow work differently inside of if statement conditional?
(2 answers)
Why does integer overflow on x86 with GCC cause an infinite loop?
(6 answers)
Closed 10 months ago.
In my program, I found the loop unable to exit correctly when i is int32_t. It seems like integer overflow, and is much larger than 10, and the loop does not stop.
Please tell me what happened and how I can avoid this error in a large project.
#include <iostream>
#include <stdint.h>
int f(int n){
for (int32_t i = 0; i < 10; ++i)
{
int64_t time = 4500000000 + (i) * 500000000;
std::cout << time<< " i: " << i << std::endl;
}
return 0;
}
int main ()
{
return f(10);
}
code link
If you use GCC 11.2.0 and the -Wall -O2 options, you will see a warning about undefined behavior:
test.cpp: In function 'int f(int)':
test.cpp:7:42: warning: iteration 5 invokes undefined behavior [-Waggressive-loop-optimizations]
7 | int64_t time = 4500000000 + (i) * 500000000;
| ~~~~^~~~~~~~~~~
test.cpp:5:27: note: within this loop
5 | for (int32_t i = 0; i < 10; ++i)
| ~~^~~~
The compiler knows that 5 * 500000000 is too large to fit in an int (which is typically 32-bit). Signed integer overflow is undefined behavior in C++. Therefore, the compiler is free to assume that this overflow never happens, so it will assume that i can never reach 10, so it can get rid of the part of your for loop that checks i < 10. I know that sounds crazy, but if your program does undefined behavior, the compiler is free to do whatever it wants.
Just add some casts to specify that you want to do 64-bit arithmetic. This eliminates the warnings, the overflows, and the undefined behavior:
int64_t time = (int64_t)4500000000 + i * (int64_t)500000000;
Update: For a larger project that could have more bugs, you might consider using GCC's -fwrapv option, which makes the behavior of signed integer overflow be defined. You could also use -fsanitize=signed-integer-overflow or -fsanitize=undefined to detect these issues at run time, if your toolchain supports those options.

Same code gives different output on Microsoft studio compared to other compilers [duplicate]

This question already has answers here:
How do we explain the result of the expression (++x)+(++x)+(++x)? [duplicate]
(5 answers)
Closed 3 years ago.
int a = 10;
a = a++;
cout << a<<" ";
a++;
cout << a;
In microsoft Visual its output is 11 12
And in other compilers (like codechef and codeforces) its output is 10 11
This question's Output was asked in some mcq paper and the correct answer is 10 11 but can any1 also explain how
a = a++;
++a;
cout<<a;
produces output of 11 does a = a++ does't do anything?
a = a++; is not a correct statement due to lack of sequence point or being unsequenced(C++11).
undefined behavior - there are no restrictions on the behavior of the program. Examples of undefined behavior are memory accesses outside of array bounds, signed integer overflow, null pointer dereference, more than one modifications of the same scalar in an expression without any intermediate sequence point (until C++11)that are unsequenced (since C++11), access to an object through a pointer of a different type, etc. Compilers are not required to diagnose undefined behavior (although many simple situations are diagnosed), and the compiled program is not required to do anything meaningful.
https://en.cppreference.com/w/cpp/language/ub

Assignment or increment operator in c++ [duplicate]

This question already has answers here:
Undefined behavior and sequence points
(5 answers)
What's the reason for letting the semantics of a=a++ be undefined?
(8 answers)
Closed 5 years ago.
I have been running this code at different compilers. At Microsft VS. it prints 1, but at gcc, it prints 0. What is the result according to the standard c++. I don't if there is standardization for this piece of code as well.
int a=0;
a=a++;
cout << a<< endl;
a=a++ is undefined behavior. Not only is there no standard definition for what will happen, it isn't even guaranteed to always do the same thing between different runs.
It could print 0 now, 1 the next time, and crash your program on the third attempt.