1

I am developing an application that uses NI-DAQ and below are some methods which were given by the provider.

void someMethod(Calibration *cal, float myArray[], float result[]) 
{
    newMethod(&cal->rt,myArray,result,cal->cfg.TempCompEnabled);
}

void newMethod(RTCoefs *coefs, double myArray[],float result[],BOOL tempcomp) 
{
float newMyArray[6];
    unsigned short i;

    for (i=0; i < 6; i++) 
    {
         newMyArray[i]=myArray[i];
    }

}

I basically call someMethod(), providing an array with six elements ( [6] ) for both myArray[] and result[]. As you can see in the code, afterwards the newMethod() is called, and float myArray[6] is passed to the double myArray[] argument (I really do not understand why the developer of this code chose to use a double array, since the only array declared inside the newMethod() is a float type).

Now here comes my problem: inside the for loop, some values are passed without any problem, but when the fourth and fifth values are passed to newMyArray[], it receives "-1.#INF0000" for both values. At first glance, I thought that it would be some garbage value, but "-1.#INF0000" is there at every execution.

I know that C language can be tricky sometimes, but I really do not know why this is happening...

nightshade
  • 638
  • 5
  • 15
Mudkip
  • 373
  • 6
  • 27
  • 2
    which language is this? C and C++ are different. – M.M Jun 26 '14 at 08:35
  • 1
    @MattMcNabb Not in this case. – James Kanze Jun 26 '14 at 08:36
  • 1
    @JamesKanze in C++ there could be other overloads of newMethod (amongst other possibilities) – M.M Jun 26 '14 at 08:38
  • It would help if you gave us the values in `myArray`. I suspect range issues. – Jack Aidley Jun 26 '14 at 08:39
  • 2
    @Mudkip in C you must get a compilation error for the line `newMethod(&cal->rt,myArray,result,cal->cfg.TempCompEnabled);` because `float *` cannot be converted to match `double *`. This error should not be ignored! – M.M Jun 26 '14 at 08:39
  • You can convert from float to double without fear but if you try to do the other way you might get the number being truncated or some other funny stuff – nightshade Jun 26 '14 at 08:39
  • @MattMcNabb: I think it would be a compilation error in C++, a warning in C (on a compiler with warnings properly configured). – Medinoc Jun 26 '14 at 08:48
  • @Medinoc the C and C++ standards don't distinguish between "warnings" and "errors", in both languages, if there was a prototype in scope then the compiler must emit a message (but it could go on and generate a bogus executable anyway) – M.M Jun 26 '14 at 08:50

3 Answers3

6

The second parameter to newMethod has type double *. But you pass to it a value of type float *.

In C++, or in C if there was a prototype of newMethod in scope, this must generate a compilation error. There is no implicit conversion between pointer types , except for void *.

However, in C, if there is no prototype in scope then you may get no warning; just undefined behaviour at runtime because the function was called with arguments of different type (after default argument promotions) to that with which it was defined.

If there is a non-prototype declaration of newMethod in scope then you get no warning; if there was no declaration at all then in C89 the code is legal (i.e. warning is optional) , but in C99 it must warn that newMethod was called without being declared.

(So it is important whether this is a C program or a C++ program).

If you are in C and getting no warning, add a prototype before all this:

void newMethod(RTCoefs *coefs, double myArray[],float result[],BOOL tempcomp) ;

Then you will get a compiler error.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • If there was no prototype, then someMethod wouldn't be able to call newMethod, since the former seems to be defined above the latter. It would seem that the problem is just caused by a bad compiler. – Lundin Jun 26 '14 at 08:52
  • 1
    edited to clarify that point. In C you can have non-prototype declarations of functions (i.e. `void newMethod();`) – M.M Jun 26 '14 at 08:53
  • I can smell Visual Studio. Funny how "Visual Studio" and "bad compiler" always pop up in the same context. – Lundin Jun 26 '14 at 08:55
  • Solved! Just changed the the array type from double to float inside the newMethod() argument. Thank you! – Mudkip Jun 26 '14 at 09:26
  • You mean in the function signature of newMethod? OK, and then you might be able to get rid of `newMyArray` too. If you didn't get a compiler error first time around then please do add a prototype, it might let the compiler detect other cases of bad calls like this. – M.M Jun 26 '14 at 09:36
  • It would also be wise to add in some const-correctness , e.g. if `myArray` is input-only then have the function be `void newMethod(RTCoefs *coefs, double const *myArray,float *result,BOOL tempcomp);` . Then the compiler will also guard against accidental changes to `myArray`'s contents within the function. – M.M Jun 26 '14 at 09:38
3

The problem is with the types and the fact that arrays decays to pointers when passed to functions. So when you pass a pointer to a float array to someMethod it in turn pass it on as a pointer to an array of double to newMethod. And as you (should) know the size of float and the size of double is not the same, so in newMethod the code is reading data out of bounds from the initial (float) array you passed which leads to undefined behavior.

The compiler should have given you warnings about that.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

-1.#INF0000 is, I believe, the MSC representation of a negative infinity. Which is what you get from a double to float conversion when the value of the double is too big to be represented in a float.

James Kanze
  • 150,581
  • 18
  • 184
  • 329