freopen's blog

By freopen, 12 years ago, In Russian

... это не g++, это minGW.

MinGW (англ. Minimalist GNU for Windows), ранее mingw32, — нативный программный порт GNU Compiler Collection (GCC) под Microsoft Windows, вместе с набором свободно распространяемых библиотек импорта и заголовочных файлов для Windows API. (Википедия).

Я плохо понимаю, как можно портировать на другую платформу приложение с открытым кодом, при этом наделать кучу ошибок, которые, казалось бы, случайно не сделаешь, при этом стать популярным. Но вот как-то так и вышло.

Вот, например, что вас может ждать, если вы будете использовать компилятор, который на этом сайте гордо зовется g++. Попробуем запустить вот такой код:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;

bool fail1=0, fail2=0;

bool lsw0(int a, int b) {
  // В исходном массиве нет нулей, 
  // компаратор не может запуститься от нулевого аргумента
  if (a==0 || b==0) if (!fail1) {fail1 = 1; cout << "Fail #1" << endl;}
  // Арктангенс от положительного числа и нуля согласно man pages
  // равен pi/2 независимо от первого аргумента
  if (atan2(a,0) < atan2(b,0)) if (!fail2) {fail2 = 1; cout << "Fail #2" << endl;}
  // Это отношение транзитивно, если арктангенс зависит только от входных данных
  return atan2(max(a,1),0) < atan2(max(b,1),0);
}

int main () {
  #ifdef __MINGW32__
  cout << "I'm running on MinGW 32" << endl;
  #endif
  vector<int> perm;
  for (int j=1;j<250;j++) {
    perm.push_back(j);
  }
  sort(perm.begin(),perm.end(),lsw0);
}

На нормальных компиляторах этот код отработает без ошибок и ничего не выведет на экран. Но не на MinGW! Фейл первый: если запустить сортировку сортировать массив (1,2,...,249), может ли компаратор запуститься от нулевых аргументов? Как правило, функцию сортировки совершенно не волнует отношение порядка для элементов вне массива. Но MinGW оказался очень любопытным компилятором и таки заглянул туда. Фейл второй: как вы думаете, что больше: угол от OX до вектора (0;1) или угол от OX до вектора (0,2). Вот MinGW искренне думает, что они вполне себе могут отличаться. Ну и наконец, пишем более-менее стандартный компаратор, который отработает верно независимо от реализации atan2, лишь бы сам atan2 не рухнул. Но и здесь нас ждет провал, сортировка падает в RE.

Вывод: если вы не желаете экстремального поиска багов компилятора во время контеста, используйте компилятор Visual C++. Также, наверное, стоит сменить название компилятора в системе с g++ на MinGW, чтобы новички не удивлялись, почему в системе код падает, а у них на локальном компьютере все работает.

UPD. SkyHawk подсказывает, что g++ может вызывать fail #1, если компаратор не является strict weak ordering. Однако, MinGW умеет так делать даже при верном компараторе.

UPD2. Делаю вывод, что все эти фейлы порождаются одной и той же ошибкой: в MinGW strict weak ordering не выполняется даже для double.

UPD3. Ссылка от DAle про причины подобных ошибок при операциях с плавающей точкой.

  • Vote: I like it
  • -1
  • Vote: I do not like it