zero4338's blog

By zero4338, history, 7 weeks ago, In English

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;
}
 
 
 
 
  • Vote: I like it
  • +109
  • Vote: I do not like it

»
7 weeks ago, # |
  Vote: I like it +16 Vote: I do not like it

upd: It also outputs -8 on my computer when using -O2.

»
7 weeks ago, # |
  Vote: I like it +46 Vote: I do not like it

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.

»
7 weeks ago, # |
  Vote: I like it +21 Vote: I do not like it

Seemed like -O2 change the execution order, you can add "volatile" before the variable to avoid it.

  • »
    »
    7 weeks ago, # ^ |
      Vote: I like it +16 Vote: I do not like it
    Spoiler
  • »
    »
    7 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    So when will this happen?
    It bothers to add volatile before all variables.

    • »
      »
      »
      7 weeks ago, # ^ |
      Rev. 3   Vote: I like it +8 Vote: I do not like it

      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.

»
7 weeks ago, # |
Rev. 3   Vote: I like it +49 Vote: I do not like it

On Codeforces, merely changing the line if(J==0)f[J]={0,2}; to if (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 line printf("%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.

  • »
    »
    7 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    The code is not constructed by me.
    MoRanSky find this and he posted a blog on uoj(in Chinese).
    The code here is simplified from that blog.

»
7 weeks ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Adding either of #define _GLIBCXX_ASSERTIONS or #define _GLIBCXX_DEBUG "fix" the issue. Don't know why.

»
7 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

I changed int mg(pair<int,int>x,pair<int,int>y) to int mg(pair<int,int>x, const pair<int,int> &y) and it outputs 2 but I didn't know why.

»
7 weeks ago, # |
  Vote: I like it +16 Vote: I do not like it

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.