compressonator
compressonator copied to clipboard
Use of isnan in CMP_Core BC7 encode
isnan
and isinf
are functions seem to cause headaches in my experience since their definition seems to be unreliable across compilers. When compiling BC7_Encode_Kernel.cpp
with GCC 5 you get an undefined error:
BC7_Encode_Kernel.cpp: In function ‘void GetProjectedIndex(CGV_INDEX*, CGV_IMAGE*, CGV_INT, CGV_ENTRIES)’:
BC7_Encode_Kernel.cpp:1001:23: error: ‘isnan’ was not declared in this scope
if (isnan(img_diff)) return;
^
BC7_Encode_Kernel.cpp:1001:23: note: suggested alternative:
In file included from Common_Def.h:73:0,
from BC7_Encode_Kernel.h:32,
from BC7_Encode_Kernel.cpp:43:
/usr/include/c++/5/cmath:648:5: note: ‘std::isnan’
isnan(_Tp __x)
How exactly isnan should be accessed is problematic because it depends on the compiler version and on whether you include <cmath>
or <math.h>
or both, and in what order, including other system headers that might include one or the other. In CMP_Core it seems both are included - cmp_math_vec4.h
includes <math.h>
but other headers like cmd_math_func.h
and Common_Def.h
include <cmath>
.
I believe adding a using std::isnan
to the top of BC7_Encode_Kernel.cpp
when building for CPU might work around this issue in a cross-compiler way. The other alternative is to either re-implement isnan (some projects do that, either with manual bit-inspection or forwarding to different standard functions depending on compiler detection).
If GCC 5 is below the minspec considered for this repository then please feel free to close this as that seems to be the only compiler I found that breaks, and I believe the headers were fixed deliberately to avoid this kind of problem in GCC 6 and up.
@baldurk replacing isnan() with this definition
#define cmp_isnan(x) ((x) != (x))
AFAIK that can be quite dangerous since depending on compiler settings it will be optimised out entirely. If you're implementing it by hand I believe it's likely better to check bit patterns with a union or memcpy.
@baldurk changing to std definition for cpu as suggested
#ifdef ASPM_GPU #define cmp_isnan(x) isnan(x) #else #define cmp_isnan(x) std::isnan(x) #endif
The issue has been resolved in current release v4.4