'переменная' может использоваться неинициализированной в этой функции, иметь рабочий обходной путь, но не понимаю, почему - PullRequest
2 голосов
/ 31 марта 2020

Я искал и нашел много похожих вопросов (с несомненно хорошими ответами), но я не нашел тот, который полностью понимаю. Я нашел решение, которое работает, и я действительно просто пытаюсь понять, что я делаю неправильно в первом примере ...

Я написал функцию, которая вычисляет шаг / крен из raw значения акселерометра с объявлением:

uint8_t calcPitchRoll (imu_t * imu, float * pitch, float * roll);

Вызывающая функция выглядит следующим образом (номера строк для справки):

518 float * pRollValue, * pPitchValue; // prepare pointers to floats to store results
519 *pRollValue = 0; // initialize variables
520 *pPitchValue = 0; // initialize variables
521 calcPitchRoll (imu, pPitchValue, pRollValue);

Однако это приводит к предупреждениям компилятора:

main.c:519:25: warning: 'pRollValue' may be used uninitialized in this function
main.c:521:26: warning: 'pPitchValue' may be used uninitialized in this function

Однако работает следующее:

float PitchValue, RollValue = 0;
float * pRollValue = &RollValue;
float * pPitchValue = &PitchValue;
calcPitchRoll (imu, pPitchValue, pRollValue);

Мне кажется, что оба примера имеют одинаковое «состояние» при вызове функции calcPitchRoll, но компилятор не согласен.

То, что я (думаю, я) понял, это то, что *pRollValue = 0 записывает это значение в переменную, так что я бы подумал, что в этой точке переменной выделено место и значение. Это неправильное понимание?

1 Ответ

3 голосов
/ 31 марта 2020

В ваших двух примерах кода есть огромная разница.

Посмотрите на это:

518 float * pRollValue, * pPitchValue;  // Here pRollValue is uninitialized
519 *pRollValue = 0;                    // Here you dereference pRollValue (due to the *)
    ^        
    |                           // So you dereference an uninitialized pointer
    |
    Dereference of uninitialized pointer

Здесь

float PitchValue, RollValue = 0;
float * pRollValue = &RollValue;  // You define a pointer and at the
                                  // same time you initializes it to
                                  // point to a float

Таким образом, две части кода полностью разные.

Таким образом, вы должны понимать разницу между указателем на объект типа T и объектом типа T .

Код как

float * pF;

даст вам память для удержания указателя на float , но нет места для хранения самого float. Вам нужно присвоить значение указателю, чтобы он указывал на число с плавающей точкой.

Так что вам нужно что-то вроде:

float * pF;
float myFloatVariable;
pF = &myFloatVariable;  // Now pF points to myFloatVariable

*pF = 42;               // These two statements both sets
myFloatVariable = 42;   // the variable myFloatVariable to 42

Альтернативный подход - это динамическое распределение c, например:

float * pF = malloc(sizeof *pF);
assert(pF != NULL);

*pF = 42;               // This sets the dynamic allocated float to 42
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...