Блог пользователя Errichto

Автор Errichto, 7 лет назад, По-английски
#include <vector>
int main() {
	std :: vector<int> w;
	for(int x : w);
}

The code above runs forever on my machine, after being compiled with g++ a.cpp (it first prints some warning), the same on ideone: http://ideone.com/5FodQO. Why? EDIT: As yeputons noticed, this bug was already reported by Mike Mirzayanov.

And the following code gives me RTE without any warning if compiled with g++ -O2 a.cpp — is it a compiler bug as well?

#include <bits/stdc++.h>
using namespace std;
struct Big {
	vector<int> w;
	Big(int x) {
		while(x) {
			w.push_back(x % 10);
			x /= 10;
		}
	}
	Big operator - () const {
		return Big(0) - *this;
	}
	int get(int i) const {
		if(i < (int) w.size()) return w[i];
		return 0;
	}
	Big operator - (const Big & other) const {
		Big ans(0);
		ans.w.resize(100, 0); // ans.w.resize(max(w.size(), other.w.size())); // gives RTE too
		puts("a");
		for(int i = 0; i < (int) ans.w.size(); ++i)
			ans.w[i] = get(i) - other.get(i);
			// ans.w[i] = (i < (int) w.size() ? w[i] : 0)
			//	- (i < (int) other.w.size() ? other.w[i] : 0); // gives RTE too
		puts("b");
		return ans;
	}
};
int main() {
	//Big(0) - Big(57); // this line works fine
	-Big(57);
}
Теги c++
  • Проголосовать: нравится
  • +77
  • Проголосовать: не нравится

»
7 лет назад, # |
  Проголосовать: нравится +12 Проголосовать: не нравится

Looks like compiler's bug. Would you mind sharing your command line and GCC version?

  • »
    »
    7 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    I've just tried compiling a few versions in various ways. Here is my gcc version:

    gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)

    The code above gives me TLE after compiling with gcc -std=c++03 -O2 or g++ -std=c++03 -O2 (Edit: well, the same happens after compiling with g++ without extra flags). In both cases it gives me a warning though:

    x.cpp:4:14: warning: range-based ‘for’ loops only available with -std=c++11 or -std=gnu++11
      for(int x : w);
    

    I also have a longer piece of code that leads to RTE (there were no warnings during the compilation):

    code
»
7 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Looks like really compiler's bug. In VC++ it works. http://rextester.com/SRIET30307

»
7 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

I was able to shorten the latter example even more:

#include <vector>

struct Foo {
  std::vector<int> w;
 
  Foo bar() const {
    Foo ans;
    ans.w.resize(2, 0);
    for (int i = 0; i < (int)ans.w.size(); ++i) {
      ans.w[i] = ((i < (int)w.size()) ? w[i] : 0);
    }
    return ans;
  }
};
int main() {
  Foo().bar();
}

However, I was able to reproduce this bug on the exact same compiler as Errichto has, which is the latest GCC available in Ubuntu 16.04. I think it's an Ubuntu-related bug.

»
7 лет назад, # |
Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

Add these lines to the end of the constructor:

if (w.empty())
    w.push_back(0);

Apparently, it's usual Out-Of-Bound access.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    I still don't understand why g++ decided to drop size check. But i found another way to avoid crash — just cast i in get method to size_t instead of casting size to int (or just use size_t for indexing and avoid casts all together).

    Standard explicitly says that cast of a value of an unsigned type to a signed type is safe if the value can be represented in the destination type. In this case we can be sure that the condition holds so it must be compiler bug.

»
7 лет назад, # |
  Проголосовать: нравится +20 Проголосовать: не нравится

The first bug happened during the second day of IOI 2016 with the problem messy. The grader contained the range-based for, and the script that all contestants contained the --std=c++11 option in a compile line, so everything almost worked fine for everybody. But those contestants who decided to use some IDE and compile their solution with a grader manually without the --std=c++11 option faced the similar issue and it took us a while to understand what's happening.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    I can't believe that it happened to others too:))I thought I'm the only one stupid enough to not be able to get the grader working.