разрешить [-Werror = Maybe-uninitialized] с указателем функции, который инициализируется только во время выполнения - PullRequest
0 голосов
/ 11 октября 2019

Я пишу кусок кода на C11, который должен облегчить мою жизнь в дальнейшем в программе. У меня есть общая функция intersect, которую я хочу вызвать. Однако в зависимости от некоторых обстоятельств эта функция intersect может фактически быть другой функцией.

Обратите внимание, что тип указателя третьего аргумента intersect зависит от регистра переключателя, поэтому я не могу обобщитьit.

Такая же ошибка также появляется для getnormal.

Ошибка:

error: ‘intersect’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   57 |   current_t = intersect(origin, direction, objects[i]);
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Код:


float inline iPlane(vec3 origin, vec3 direction, plane * pla);
float inline iTriangle(vec3 origin, vec3 direction, triangle * tri);
float inline iSphere(vec3 origin, vec3 direction, sphere * sph);

vec3 inline nTriangle(triangle * obj, vec3 position);
vec3 inline nPlane(plane * obj, vec3 position);
vec3 inline nSphere(sphere * obj, vec3 position);


    float current_t;

    vec3 (*getnormal)();
    float (*intersect)();

    object * nearest_obj = NULL;
    for (int i = 0; i < object_count; ++i)
    {
        switch(objects[i]->shape){ // shape = enum{sphereobj, triangleobj, planeobj}
            case triangleobj:
                getnormal = &nTriangle; // real function that exists
                intersect = &iTriangle; // also a real function that exists
                break;
            case sphereobj:
                getnormal = &nSphere;
                intersect = &iSphere;
                break;
            case planeobj:
                getnormal = &nPlane;
                intersect = &iPlane;
                break;
        }

        current_t = intersect(origin, direction, objects[i]); // error here
    }

Ответы [ 2 ]

3 голосов
/ 11 октября 2019

Чтобы избавиться от предупреждения, просто инициализируйте переменную-указатель функции равной 0.

float (*intersect)() = NULL;

, а затем перед использованием убедитесь, что она инициализирована (на случай, если все перечисления не включены вswitch оператор, в этом случае будет выдано другое предупреждение, но лучше, чем потом сожалеть)

assert (intersect);

или без утверждения (которое может быть устранено некоторыми переключателями компилятора)

if (!intersect)
{
  // handle the error
}

Если дело может произойти:

if (intersect)
{
   current_t = intersect(origin, direction, objects[i]);
}
else
{
   current_t = 0.0; // some default value else you get the "uninitialized error" with current_t
}
3 голосов
/ 11 октября 2019

Компилятор не может гарантировать, что objects[i]->shape является просто значением из перечисления. С точки зрения компилятора objects[i]->shape - это просто значение int.

Быстрое решение состоит в том, чтобы добавить регистр default, который использует некоторые разумные значения по умолчанию.

Другое решение -инициализировать указатели на NULL, а затем проверить их перед использованием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...