[MDEV-21082] isnan/isinf compilation errors, isfinite warnings on MacOS Created: 2019-11-11  Updated: 2019-11-19  Resolved: 2019-11-19

Status: Closed
Project: MariaDB Server
Component/s: Compiling
Affects Version/s: 10.2
Fix Version/s: 10.2.30

Type: Bug Priority: Critical
Reporter: Alexey Bychko (Inactive) Assignee: Vladislav Lesin
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by MDEV-21050 warning: 'finite' is deprecated: firs... Closed

 Description   

10.2 ES compilation fails under current MacOS due to incomplete or wrong definitions:

#if (__cplusplus >= 201103L)
#define my_isnan(x) std::isnan(x)
#else /* (__cplusplus >= 201103L) */
#ifndef HAVE_ISNAN
#define isnan(x) ((x) != (x))
#endif
#define my_isnan(x) isnan(x)
#endif /* (__cplusplus >= 201103L) */
 
#if (__cplusplus >= 201103L)
#define my_isinf(x) std::isinf(x)
#else /* (__cplusplus >= 201103L) */
#ifdef HAVE_ISINF
#define my_isinf(X) isinf(X)
#else /* !HAVE_ISINF */
#define my_isinf(X) (!finite(X) && !isnan(X))
#endif /* !HAVE_ISINF */
#endif /* (__cplusplus >= 201103L) */

it results in compilation failure:

[ 34%] Building CXX object sql/CMakeFiles/sql.dir/field.cc.o
/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/sql/field.cc:4824:7: error: no member named 'isnan' in namespace 'std'; did you mean simply 'isnan'?
  if (my_isnan(res))
      ^~~~~~~~~~~~~
/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/include/my_global.h:826:21: note: expanded from macro 'my_isnan'
#define my_isnan(x) std::isnan(x)
                    ^~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/math.h:541:1: note: 'isnan' declared here
isnan(long double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
^
/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/sql/field.cc:4846:10: error: no member named 'isinf' in namespace 'std'; did you mean simply 'isinf'?
    if (!my_isinf(res))
         ^~~~~~~~~~~~~
/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/include/my_global.h:835:21: note: expanded from macro 'my_isinf'
#define my_isinf(x) std::isinf(x)
                    ^~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/math.h:497:1: note: 'isinf' declared here
isinf(long double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
^
2 errors generated.
make[2]: *** [sql/CMakeFiles/sql.dir/field.cc.o] Error 1
make[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2
make: *** [all] Error 2

to solve that we might need to define 3d matrix - HAVE_

{IFINF,ISNAN},platform, compiler to handle cases like following:
linux && gcc || clang (+ versions if needed)
apple && clang (+ versions if needed)
HAVE_{IFINF,ISNAN}

|| default fallback
std::isnan or isnan() from math.h

10.2 built successfully with properly defined my_isnan() and my_isinf()

Besides there is another issue on MacOS 10.9:

/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/sql/item_func.h:244:12: warning: 'finite' is deprecated: first deprecated in macOS 10.9 - Use
 
      `isfinite((double)x)` instead. [-Wdeprecated-declarations]
 
    return isfinite(value) ? value : raise_float_overflow();
 
           ^
 
/Users/abychko/GitHub/MariaDB/MariaDBEnterprise/include/my_global.h:820:21: note: expanded from macro 'isfinite'
 
#define isfinite(x) finite(x)
 
                    ^
 
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/math.h:749:12: note: 'finite' has been explicitly marked deprecated here
 
extern int finite(double)



 Comments   
Comment by Vladislav Lesin [ 2019-11-19 ]

On some platforms(like Ubuntu 16.04) math.h contains isnan/isinf
definition only for C99 standard. If some code is compiled with C++11
standard, math.h does not contain isnan/isinf definitions, it's supposed
cmath header and std::isnan, std::isinf, std::isfinite must be used instead
of math.h for C++11.

Note CHECK_SYMBOL_EXISTS(isnan math.h HAVE_ISNAN) returns
true because it uses try_compile() cmake function, which does not apply
CMAKE_CXX_FLAGS or CMAKE_CXX_STANDARD in cmake <= 3.7(default cmake
version for Ubuntu 16.04 is 3.5), and the code, passed as an argument to
try_compile(), is compiled under default C99 standard(if the
correspondent compilation flag is not set explicitly in CMAKE_REQUIRED_FLAGS).

So if we use CHECK_SYMBOL_EXISTS(...) on Ubuntu 16.04 we have
HAVE_ISNAN/HAVE_ISINF set to true, but isnan/isinf are not defined
in math.h if the code is compiled under C++11 standard, what is true
for ES and 10.4+ CS.

To use std::isnan/std::isinf we must include cmath. It was included in
my_global.h only if "isfinite" macro is not defined and C++11 is used.
But there is another issue. On some platforms like MacOS X, "isfinite"
is defined for both C99 and C++11 standards, so on MacOS X cmath was not
included in my_global.h, what caused compilation errors for the code which used
std::inan/std::isinf/std::isfinite. Besides "isfinite" is deprecated since MacOS 10.9,
what led to a lot of warnings during compilation.

That is why we include cmath and use std::isfinite on C++11
standard, even if "isfinite" is defined.

The solution is to use std::isnan/std::isinf/std::isfinite if the code
is compiled with C++11 standard.

The corresponding changes were already done for 10.3 CS:

commit 7ffd7fe9627d1f750a3712aebb4503e5ae8aea8e
Author: Sergey Vojtovich <svoj@mariadb.org>
Date:   Fri May 25 22:16:04 2018 +0400
    Cleanup isnan() portability checks
 
commit bc469a0bdf85400f7a63834f5b7af1a513dcdec9
Author: Sergey Vojtovich <svoj@mariadb.org>
Date:   Fri May 25 22:09:07 2018 +0400
    Cleanup isinf() portability checks
    Original problem reported by Wlad: re-compilation of 10.3 on top of 10.2
    build would cache undefined HAVE_ISINF from 10.2, whereas it is expected
    to be 1 in 10.3.
    std::isinf() seem to be available on all supported platforms.
 
commit 54999f4e75f42baca484ae436b382ca8817df1dd
Author: Sergey Vojtovich <svoj@mariadb.org>
Date:   Wed May 23 18:52:55 2018 +0400
    Use std::isfinite in C++ code
    This is addition to parent revision fixing build failures.

Generated at Thu Feb 08 09:04:27 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.