What is the best way to return an error from a function when I'm already returning a value?

前端 未结 8 1926
盖世英雄少女心
盖世英雄少女心 2020-12-13 13:42

I wrote a function in C that converts a string to an integer and returns the integer. When I call the function I also want it to let me know if the string is not a valid num

8条回答
  •  北荒
    北荒 (楼主)
    2020-12-13 14:15

    What is the best way to return an error from a function when I'm already returning a value?

    Some additional thoughts to the various answers.


    Return a structure

    Code can return a value and an error code. A concern is the proliferation of types.

    typedef struct {
      int value;
      int error;
    } int_error;
    
    int_error intval(const char *string);
    
    ...
    
    int_error = intval(some_string);
    if (int_error.error) {
      Process_Error();
    }
    
    int only_care_about_value = intval(some_string).value;
    int only_care_about_error = intval(some_string).error;
    

    Not-a-number and NULL

    Use a special value when the function return type provides it.
    Not-a-number's are not required by C, but ubiquitous.

    #include 
    #include 
    
    double y = foo(x);
    if (isnan(y)) {
      Process_Error();
    }
    
    void *ptr = bar(x);
    if (ptr == NULL) {
      Process_Error();
    }
    

    _Generic/Function Overloading

    Considering the pros & cons of error_t foo(&dest, x) vs. dest_t foo(x, &error),

    With a cascaded use of _Generic or function overloading as a compiler extension, selecting on 2 or more types, it makes sense to differentiate the underlying function called to be based on the parameters of the call, not the return value. Return the common type, the error status.

    Example: a function error_t narrow(destination_t *, source_t) that converted the value of one type to a narrower type, like long long to short and tested if the source value was in range of the target type.

    long long ll = ...; 
    int i;
    char ch; 
    error = narrow(&i, ll);
    ...
    error = narrow(&ch, i);
    

提交回复
热议问题