Get rid of the ugly design C

I inherited the (most) part of the code, which has an error tracking mechanism, where they pass a boolean to all the methods that they call, and if errors occur at different stages of execution, the method stops and returns, sometimes the default value.

Something like (BEFORE):

#include <iostream.h>
int fun1(int par1, bool& psuccess)
{
    if(par1 == 42) return 43;
    psuccess = false;
    return -1;
}
int funtoo(int a, bool& psuccess)
{
    int t = fun1(a, psuccess);
    if(!psuccess)
    {
        return -1;
    }
    return 42;
}
void funthree(int b, bool& psuccess)
{
    int h = funtoo(b, psuccess);
    if(!psuccess)
    {
         return;
    }
    cout << "Yuppi" << b;
}
int main()
{
    bool success = true;
    funthree(43, success);
    if(!success)
    {
        cout<< "Life, universe and everything have no meaning";
    }
}

Note that this is a mix of C and C ++ code, just like a project.

Now a piece of magic appears C: “someone” defined a macro somewhere:

#define SUCCES_OR_RETURN  if(!psuccess) return

And the above program becomes (AFTER):

#include<iostream.h>
int fun1(int par1, bool& psuccess)
{
    if(par1 == 42) return 43;
    psuccess = false;
    return -1;
}
int funtoo(int a, bool& psuccess)
{
    int t = fun1(a, psuccess);
    SUCCES_OR_RETURN -1;
    return 42;
}
void funthree(int b, bool& psuccess)
{
    int h = funtoo(b, psuccess);
    SUCCES_OR_RETURN ;
    std::cout << "Yuppi" << b;
}
int main()
{
    bool success = true;
    funthree(43, success);
    if(!success)
    {
        cout<< "Life, universe and everything have no meaning";
    }
}

: , , . C SUCCES_OR_RETURN .. , , return, .

, - , :

  • . C ++, , throw ( , , ). ++.
  • ++ 11, "" ++, ++. , ++ 11.
  • . , , .

Edit

, @BlueMoon, commend, , , success, - , , :)

+4
3

C ++:

, :

  • , .
  • , ​​ Windows GetLastError() OpenGL glGetError(), .
  • (, , -) , , ​​ POSIX errno.
  • , , , , POSIX strerror.
  • , , GLFW glfwSetErrorCallback.
  • , , .
  • , stderr - .
  • assert() - .

, , , , [sic] , , .

, :

libfoo_widget_container_t container = NULL;
libfoo_error_details_t error = NULL;
if (libfoo_create_widgets(12, &container, &error) != libfoo_success) {
    printf("Error creating widgets: %s\n", libfoo_error_details_c_str(error));
    libfoo_error_details_free(error);
    abort(); // goodbye, cruel world!
}

, , ( 0|1, C !).

, , goto, , SUCCES_OR_RETURN , , . , http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/

+5

. -.

: 3 , , , - .

-, "" , , .

- , .

ICU .

++ 1y , , - , expected.

, an expected<T, Err> T, - , Err. boost::variant ++ 1y std::optional. expected< T, Err > + U, expected< decltype( std::declval<T&>() + std::declval<U>(), Err > auto, . .

, , , , . , void, , .

if (berror) return error_flag_value{};

, , ; -1;.

+3

If you want to switch to full C ++, the answer will change "invalid return values" for exceptions ...

#include <iostream>
#include <exception>

using std::exception;

struct error : exception { const char* what() const throw() override { return "unsuccessful"; } };

int fun1(int par1) {
  if( par1 == 42 ) return 43;
  throw error();
}

int funtoo(int a) {
  fun1(a);
  return 42;
}

void funthree(int b) {
  funtoo(b);
  std::cout << "Yuppi " << b << "\n";
}

int main() {
  try {
    funthree(42);
  } catch(exception& e) {
    std::cout << "Life has no meaning, because " << e.what() << "\n";
  }
}

This prints Yuppi 42(if you change the call funthree(42)for funthree(43), it prints Life has no meaning, because unsuccessful...)

(live at coliru)

+1
source

Source: https://habr.com/ru/post/1539268/


All Articles