Mat::operator=(const Scalar&) incorrectly handles NaNs with floating-point images when GCC's -ffast-math flag is enabled (Bug #2056)
Description
The
if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 )test in
modules/core/src/copy.cpp
's definition of Mat::operator=(const Scalar& s)
evaluates to true when s
contains NaNs and -ffast-math
is enabled, resulting in the input Mat
being filled with zeros rather than NaNs. Compiling the following code against a version of OpenCV built with -ffast-math
reproduces the problem:
// Define a NaN value union { float f; uint32_t i; } nan; nan.i=0x7FC00000; // Assign nan.f to image cv::Mat nanTest(1,1,CV_32FC1); nanTest=cv::Scalar(nan.f); // Print results std::cout<<"nan.f="<<nan.f<<std::endl; std::cout<<"nanTest.at<float>(0,0)="<<nanTest.at<float>(0,0)<<std::endl;
To show that -ffast-math
is the cause of the problem, compile the following program:
#include <iostream> #include <cstdint> int main(int argc, char** argv) { union { float f; uint32_t i; } nan; nan.i=0x7FC00000; std::cout<<"nan.f==0 = "<<(nan.f==0)<<std::endl; return 0; }
with
g++ -std=c++0x -ffast-math -o TestFastMath Test.cpp && g++ -std=c++0x -o Test Test.cpp
./Test
produces the output nan.f==0 = 0
, whereas ./TestFastMath
produces the output nan.f==0 = 1
.
The problem occurs with the build of OpenCV 2.3.1 that's available from the Ubuntu 12.04 repository, which I presume was built with -ffast-math
enabled. I have just downloaded and built OpenCV 2.4.1, and -ffast-math
was disabled by default, so the problem does not occur. If you must allow users to build OpenCV with -ffast-math
, please consider using something like the following function to test whether or not the cv::Scalar
is zero instead:
inline bool isZero(const double v) { union {double d; uint64_t i;} u; u.d=v; return u.i==0; }
Associated revisions
Fixed "arr = NaN" case (bug #2056)
Merge pull request #2056 from asmorkalov:java_core_cuda_wrappers
History
Updated by Ose Pedro over 12 years ago
Or alternatively, given that there are probably a lot of places in OpenCV where a floating-point number is compared to a literal, perhaps it would be more generally helpful to put a warning somewhere in the documentation about the use of -ffast-math
with NaNs?
Updated by Ose Pedro over 12 years ago
Oh, in fact http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html says that -ffast-math
enables -ffinite-math-only
, which "Allow[s] optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs". Compiling the example program I gave above with -ffinite-math-only
instead of -ffast-math
shows that -ffinite-math-only
is in fact the root cause of the problem.
Updated by Andrey Kamaev over 12 years ago
Vadim, are we supporting -ffast-math
?
- Category set to build/install
- Assignee set to Vadim Pisarevsky
Updated by Vadim Pisarevsky over 12 years ago
- Target version deleted ()
- Category changed from build/install to core
- Assignee deleted (
Vadim Pisarevsky)
Updated by Vadim Pisarevsky over 12 years ago
fixed in df8364ce
- Status changed from Open to Done
- Assignee set to Vadim Pisarevsky
Updated by Andrey Kamaev about 12 years ago
- Target version set to 2.4.3