C: Сгенерировать ошибку при проверке параметров или позволить ей попасть в вентилятор? - PullRequest
5 голосов
/ 07 сентября 2010

У меня вопрос простого дизайна (?).

Я пишу простую программу, в которой есть пара функций, которые выглядят следующим образом.

float foo (float* m,size_t n){

   float result;
   //do some calculations, for example a sum 


   return result / n;
}

У меня есть пара вопросов по этому поводу, я не собираюсь открывать какую-то священную войну.

Должен ли я добавить проверку вменяемости на n?Если так, как я должен сообщить вызывающей стороне?

Возвращение -1 выглядит странно на поплавках;

float foo(float *m,size_t n){
     if (n == 0) return -1f

     ...
  }

Мой другой параметр - это выходной параметр

float foo(float *m,size_t n, int *error){

        if (n==0){
           *error = 1;
            return 0f;
        }
       ...
}

обновление

Это своего рода игрушечная программа, просто пытающаяся попрактиковаться.Вопрос превосходит этот факт.Может быть, мне следует перефразировать: «Как обрабатывать ошибки без (OOP) исключений».

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

Anyмысли?Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 07 сентября 2010

Полагаю, ваш out parameter хороший вариант.Но я думаю, что было бы лучше в противном случае.Используйте параметр out, чтобы получить результат и возвращаемое значение, чтобы обозначить статус вызова.Вот так

int foo(float *m, size_t n, float* result)
{
  if(someFailureCondition)
    return ERROR; // ERROR being an error integer
  // else
  // do some calculation
  // set your result
  return NO_ERROR; // NO_ERROR being an integer
}

Редактировать: Возвращаемое значение может быть более подробным для обозначения текущего состояния параметра out.Смотрите комментарий Джеймслина!

2 голосов
/ 07 сентября 2010

Если -1 все равно не будет возвращена функцией, обязательно верните -1.Но если передача n = 0 не нарушит функцию, то в этом нет необходимости.Я предполагаю, что n - это размер массива m.

Обработка ошибок является вопросом предпочтения.OpenGL обрабатывает ошибки, возвращая код ошибки (-1 или иначе) в случае сбоя функции.Код ошибки возвращается через вызов GetLastError () (или что-то в этом роде).Это кажется идеальным решением для обработки ошибок.

1 голос
/ 07 сентября 2010

Вы должны сообщить вызывающим абонентам, какова семантика вашей функции, четко документируя ваш код.

Каков контракт с вашей функцией? Если от абонентов требуется не передавать 0 для n, то это необходимо объяснить, и функция должна использовать assert для проверки того, что эти требования выполнены. Логические ошибки должны быть обнаружены на ранней стадии, и эти сбои должны быть как можно более впечатляющими.

Теперь, если вы пишете код для библиотеки, которая будет использоваться другими разработчиками и обеспокоена тем, что люди будут компилировать с отключенным assert, то разумно объединить это с более мягким режимом сбоя, который всегда включен: 1010 *

if (n == 0)
{
    assert(0);
    return NAN; /* Or return some error code */
}
1 голос
/ 07 сентября 2010

Существуют специальные значения с плавающей запятой, которые вы можете использовать, если хотите - например, если ваша реализация с плавающей запятой поддерживает тихие NaN (Not-a-Number), тогда вы можете использовать макрос NAN из math.h:

#include <math.h>
float foo(float *m,size_t n)
{
     if (n == 0) return NAN;

     ...
}
...