Странное поведение при передаче значений из массива с плавающей точкой в ​​двойной массив (C, C ++)

Я разрабатываю приложение, которое использует NI-DAQ, и ниже приведены некоторые методы, которые были предоставлены поставщиком.

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];
}

}

Я в основном вызываю someMethod (), предоставляя массив с шестью элементами ([6]) для myArray [] и result []. Как вы можете видеть в коде, впоследствии вызывается newMethod (), и float myArray [6] передается в двойной аргумент myArray [] (я действительно не понимаю, почему разработчик этого кода решил использовать двойной массив, поскольку единственный массив, объявленный внутри newMethod (), является типом с плавающей запятой).

Теперь возникает моя проблема: внутри цикла for некоторые значения передаются без проблем, но когда четвертое и пятое значения передаются в newMyArray [], он получает «-1. # INF0000» для обоих значений. На первый взгляд, я думал, что это будет какое-то мусорное значение, но «-1. # INF0000» присутствует при каждом выполнении.

Я знаю, что язык C иногда бывает сложным, но я действительно не знаю, почему это происходит …

1

Решение

Второй параметр для newMethod имеет тип double *, Но вы передаете ему значение типа float *,

В C ++ или в C, если был прототип newMethod в области видимости это должно привести к ошибке компиляции. Не существует неявного преобразования между типами указателей, за исключением void *,

Однако в C, если в области видимости нет прототипа, вы можете не получать предупреждения; просто неопределенное поведение во время выполнения, потому что функция была вызвана с аргументами другого типа (после продвижения аргументов по умолчанию) к тому, с которым она была определена.

Если есть объявление не прототипа newMethod по объему вы не получите предупреждения; если не было никакого объявления вообще, то в C89 код является законным (то есть предупреждение является необязательным), но в C99 он должен предупредить, что newMethod был вызван без объявления.

(Поэтому важно, будет ли это программа на C или C ++).

Если вы находитесь в C и не получаете предупреждения, добавьте прототип перед всем этим:

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

Тогда вы получите ошибку компилятора.

6

Другие решения

Проблема заключается в типах и в том, что массивы распадаются на указатели при передаче в функции. Поэтому, когда вы передаете указатель на float массив для someMethod он, в свою очередь, передает его как указатель на массив double в newMethod, И как вы (должны) знать размер float и размер double не то же самое, поэтому в newMethod код читает данные за пределами начального (float) массив, который вы передали, что приводит к неопределенное поведение.

Компилятор должен был предупредить вас об этом.

3

-1.#INF0000 Я полагаю, что MSC представляет
отрицательная бесконечность. Что вы получаете от двойного до
преобразование с плавающей запятой, когда значение double слишком велико
представлены в поплавке.

0
По вопросам рекламы [email protected]