I've written a code that perform mathematical calculations using IIR filters and histograms. The code is supposed to be 100% portable, is reentrant, makes no system call (but memset), has double precision const and initialized variables, and only includes math.h, string.h, stdint.h and stddef.h. It's been made to run in an embedded processor.
When compiling and running the code using Windows MinGW GCC or Borland C++ it will pass all the unit tests. That doesn't happen on the Linux64 GCC platform. Further investigation has shown that the algorithm becomes lightly unstable and the output value doesn't converge to a stable result, instead, the result goes slowly to infinite, so one of the tests will fail.
Most of the code is using double floating-point precision, it also uses single precision in some variables.
I need help on how to approach this problem, I must guarantee the fully portability of code, and I don't know where to look. Also, the code is big enough to be posted here, so, if you can point directions I'll follow.
This is the compile line of the module on Linux:
gcc -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/flickerModule.d" -MT"src/flickerModule.d" -o "src/flickerModule.o" "../src/flickerModule.c"
This is the compile line of the module on Windows:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -o src\flickerModule.o ..\src\flickerModule.c
Here I show all the dependencies of the code:
fanl@fanl-STI:~/WorkFelipe/Codigos/re7k_eclipsewkspace/flicker_unittest/src$ grep -H -n -E 'mem|sqrt|floor' flickerModule.c
flickerModule.c:76: memset(filt, 0x00, sizeof(struct s_filter));
flickerModule.c:81: memset(filt, 0x00, sizeof(struct s_filter));
flickerModule.c:89: memset(&histo->buf, 0x00, sizeof(uint32_t) * NUM_CLASSES);
flickerModule.c:162: return (floorf(x + 0.5));
flickerModule.c:189: memset(&histn, 0x00, sizeof(float) * NUM_CLASSES);
flickerModule.c:262: hp->Urms_meio_ciclo = sqrt(hp->Acc_Urms_meio_ciclo / NUM_AMOSTRAS_MEIO_CICLO_60Hz);
flickerModule.c:370: return (sqrtf(saida));
flickerModule.c:393: p->GanhoNormalizaEntradaFlickerMeter = 1.0 / (p->halfPeriod.Urms_meio_ciclo * sqrt(2));
flickerModule.c:419: dbg->Prms = sqrt(dbg->Acc_Prms / (NUM_AMOSTRAS_1MIN / FATOR_DOWN1));