xy::isfinite компилируется в Linux, BSD и Windows, но не в SmartOS.

Я пытаюсь перенести Quadlods на SmartOS. Он компилируется и работает на Linux и DragonFly BSD. Я не пробовал запускать его в Windows, но другие программы, использующие класс xy с методом isfinite, компилируются и запускаются в Windows. Однако, компилируя его на SmartOS, я получаю эту ошибку:

[ 15%] Building CXX object CMakeFiles/quadlods.dir/filltest.cpp.o
In file included from /usr/include/math.h:36,
                 from /opt/local/gcc9/include/c++/9.3.0/bits/std_abs.h:40,
                 from /opt/local/gcc9/include/c++/9.3.0/cstdlib:77,
                 from /opt/local/gcc9/include/c++/9.3.0/ext/string_conversions.h:41,
                 from /opt/local/gcc9/include/c++/9.3.0/bits/basic_string.h:6493,
                 from /opt/local/gcc9/include/c++/9.3.0/string:55,
                 from /opt/local/gcc9/include/c++/9.3.0/stdexcept:39,
                 from /opt/local/gcc9/include/c++/9.3.0/optional:38,
                 from /opt/local/gcc9/include/c++/9.3.0/bits/node_handle.h:39,
                 from /opt/local/gcc9/include/c++/9.3.0/bits/stl_tree.h:72,
                 from /opt/local/gcc9/include/c++/9.3.0/map:60,
                 from /home/phma/src/quadlods/quadlods.h:27,
                 from /home/phma/src/quadlods/filltest.h:25,
                 from /home/phma/src/quadlods/filltest.cpp:26:
/home/phma/src/quadlods/xy.h:35:8: error: expected ')' before '!=' token
   35 |   bool isfinite() const;
      |        ^~~~~~~~

Файл, определяющий макрос, вызывающий эту странную ошибку, — /usr/include/iso/math_c99.h:

#define isfinite(x) (__builtin_isfinite(x) != 0)

Определение класса в заголовочном файле

class xy
{
public:
  xy(double e,double n);
  xy();
  double getx() const;
  double gety() const;
  double length() const;
  bool isfinite() const;
  bool isnan() const;
  friend xy operator+(const xy &l,const xy &r);
  friend xy operator+=(xy &l,const xy &r);
  friend xy operator-=(xy &l,const xy &r);
  friend xy operator-(const xy &l,const xy &r);
  friend xy operator-(const xy &r);
  friend xy operator*(const xy &l,double r);
  friend xy operator*(double l,const xy &r);
  friend xy operator/(const xy &l,double r);
  friend xy operator/=(xy &l,double r);
  friend bool operator!=(const xy &l,const xy &r);
  friend bool operator==(const xy &l,const xy &r);
  friend xy turn90(xy a);
  friend xy turn(xy a,int angle);
  friend double dist(xy a,xy b);
protected:
  double x,y;
};

Можно ли сделать этот компилятор на SmartOS без переименования метода? Я думал отменить определение макроса isfinite, но в другой программе (не Quadlods, чей заголовочный файл — только quadlods.h) класс xy находится в заголовочном файле библиотеки. Кроме того, метод isfinite вызывает std::isfinite.


person Pierre Abbat    schedule 17.01.2021    source источник
comment
Добро пожаловать в удивительный мир макросов. Такого рода проблемы являются точной причиной того, что макросы обычно не рекомендуются.   -  person Pete Becker    schedule 17.01.2021


Ответы (1)


Решение, которое Джонатан Перкин дал мне в IRC, заключается в том, чтобы поставить #include <cmath> сразу после включения защиты xy.h. Это отменяет определение макроса. Теперь он компилируется в Linux, BSD и SmartOS.

person Pierre Abbat    schedule 18.01.2021