Compiler bug on iMX6/WEC7 with Full Optimization

We are currently facing a compiler problem. We are using VS2008 and have Toradex WEC7 SDK V2.1 installed to compile for iMX6/WEC7. We are using the compiler setting /Ox (Full Optimization) and get a problem with following code:

class MyClass 
{
	public:
		MyClass();
		void aMethod();
	
	protected:
		double m_value;
}

MyClass::MyClass()
{
	m_value = 716.059;
}

void MyClass::aMethod() 
{
	unsigned int result = ((unsigned int)(m_value / (double)5)) - 1;

	std::ofstream outFile;
	outFile.open( "\\FlashDisk\\Debug.log", std::ios_base::app );
	outFile << "result=" << result << std::endl;;
	outFile.close();
}

The output in the file is “result=4294967295”
If we disable the Optimization (/Of) the calculation returns the correct value (“result=142”). The same code also works fine on an older System PXA320/WCE6.0 with Full Optimization.

Is there a known issue in the compiler for iMX6/WEC7?

4294967295 looks like max value of unsigned int (2^32)? This looks like a problem with data type mismatch. What happens if result is double? What if you use unsigned int(5) instead?

I assume ((unsigned int)(m_value / (double)5)) results in 0. So when subtracting 1 the result becomes ‘negative’ which corresponds to 4294967295 (0xFFFFFFFF, max. unsigned int). Actually, we could easily resolve the problem by reconstructing the formula (e.g. divide into intermediate results). However, that’s not the point. Our application was ported from PXA320/WCE6.0 to iMX6/WEC7 and we fear that there are dozens of other places were calculations might return wrong values. Disable Optimizations would also solve the issue but that’s just a workaround for us if there is no better solution.

The compiler optimized the division by 5 to a multiplication by -0.20 (don’t really understand why negative, but it’s accounting for this and correcting it later).
The root of the problem is the cast of a double to unsigned int. The behavior is not 100% defined and could behave differently depending on the compiler / os.
See this post:
https://stackoverflow.com/questions/10541200/is-the-behaviour-of-casting-a-negative-double-to-unsigned-int-defined-in-the-c-s

So to solve your problem you can change all non portable (unsigned int) casts to (unsigned)(int), or just use the same compiler that you were using for PXA320/CE6 (it will still run on CE7, but not taking full advantage of multicore)

This explanation helps us to localize other places which could behave the same way. We will just rearrange the code in order to prevent the issue in this case. Thanks a lot.