Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to return an error code for function returning size_t

Tags:

c

I have a function that probes an array and returns an array index if the probe succeeds.

In my code I have made every type concerning an array index a type_t for clarity.

What is the preffered way of retaining that clarity for this function? Should I take a pointer argument to an error variable and set that?

inline size_t
lin_search(const double *pxa, const double x, const size_t idxlow, const size_t idxhigh)
{
    for (size_t i = idxlow; i < idxhigh; i++)
    {
        if (pxa[i] <= x && pxa[i+1] > x)
            return i;
    }

    return -1; // If I change the return type to f.ex long int this works
               // but I am no longer consistent

}

Then I could use it as

index = linsearch(parray, x, 0, n - 1);
if (index == -1)
    ... not found
like image 854
luffe Avatar asked Jan 23 '16 18:01

luffe


2 Answers

One other way without "losing" size_t (size_t is the correct type for array indexes) is to return the index value in the pointer and return code as a boolean:

    bool 
    lin_search(...., size_t *index) {
        bool found = false;

        for (size_t i = idxlow; i < idxhigh; i++)  {
            if (pxa[i] <= x && pxa[i+1] > x) {
               found = true;
               *index = i;
               break;
            }
        }

    return found;
}

and you can call:

size_t index;

if ( lin_search(...., &index) ) {
  /* use 'index' */
 }

This way, you don't have to compromise with using something other than size_t and the function return type still says whether the index is found.

like image 119
P.P Avatar answered Nov 15 '22 12:11

P.P


Situations like this are not unheard of. Take for example the definition of fgetc, which reads characters:

int fgetc(FILE *stream);

fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.

This function returns a value that can be cast to unsigned char on success, and it return EOF (typically -1) on failure.

Another example is ftell, which reports the current offset in a file:

long ftell(FILE *stream);

Upon successful completion, ... ftell() returns the current offset. Otherwise, -1 is returned and errno is set to indicate the error.

File offsets are always non-negative, so returning a negative value is how errors are reported.

So I think changing the return type to long would be acceptable for a case like this.

like image 1
dbush Avatar answered Nov 15 '22 13:11

dbush