The code below outputs -8
in cf custom test when using any GNU compiler.
It should output 2
and works well on other online IDEs and my computer.
It also works well on cf when using Clang.
What's the reason for this and how to avoid it?
#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int>>f;
int mg(pair<int,int>x,pair<int,int>y)
{
return max(x.second,y.second);
}
int main()
{
f={{0,-11}};
for(int J=0;J<=0;J++)
{
f[J]=f[0];
if(J==0)f[J]={0,2};
cout<<mg({0,-8},f[J])<<endl;
}
return 0;
}
upd: It also outputs
-8
on my computer when using-O2
.I tried to compile in different gcc versions with
-O2
and it outputs-8
. If the code doesn't have any issues, you should file a bug into GCC bug tracker.Seemed like -O2 change the execution order, you can add "volatile" before the variable to avoid it.
So when will this happen?
It bothers to add
volatile
before all variables.No one knows. (idk at least)
-O2 will change the execution order to reduce the data relativity. But the situation it happened or whether it is right is almost unpredictable.
On Codeforces, merely changing the line
if(J==0)f[J]={0,2};
toif (J==0) {f[J]={0,2}; printf("HERE");}
causes the final output to turn into 2 from -8 (in addition to the added "HERE"). Same with adding the lineprintf("%d\n", J);
before the if statement. It seems that any attempt to force the compiler to acknowledge what's going on changes the result.This is very strong evidence of either a compiler bug or a strange instance of undefined behavior somewhere in the code. I don't see any reason for undefined behavior here though.
By the way, zero4338, how did you come up with this piece of code? It seems very artificially constructed.
The code is not constructed by me.
MoRanAirConditioner find this and he posted a blog on uoj(in Chinese).
The code here is simplified from that blog.
Adding either of
#define _GLIBCXX_ASSERTIONS
or#define _GLIBCXX_DEBUG
"fix" the issue. Don't know why.I changed
int mg(pair<int,int>x,pair<int,int>y)
toint mg(pair<int,int>x, const pair<int,int> &y)
and it outputs 2 but I didn't know why.To give this topic some ending, it seems somebody from this topic or from the original uoj topic has reported the bug (and also a duplicate) yesterday and it is being processed.
uh, they still didn't fixed this infinite loop
for(int i=0; i<300; ++i) cout << i*int(1e9) << endl;
162352323
What's wrong with that? Seems like UB to me.
Finite loop is infinite, what's wrong, really
Well, you wanted UB — you got it.
"Fixed on trunk sofar." https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106131#c11