There were problems when designing an application related to logging and error handling. Suppose there is such a code:

void set_opengl_attr(const bool _set_double_buff, const int _msaa_level) { // Проверить значение _msaa_level, которое должно быть равно 0, 2, 4, 8 или 16. // Если значение другое, обработать ошибку и записать в лог. // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, _msaa_level); if (_set_double_buff == true) { // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); } // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); // Проверить вернула ли функция значение 0 (успешно), если нет - записать ошибку в лог. SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); } 

If you implement all the checks, then this will be released:

 void set_opengl_attr(const bool _set_double_buff, const int _msaa_level) { if (_msaa_level != 0) { if (_msaa_level != 2 && _msaa_level != 4 && _msaa_level != 8 && _msaa_level != 16) { print_to_log("Error: Uncorrect _msaa_level. Set _msaa_level as 0"); } else { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, _msaa_level); } } if (_set_double_buff == true) { if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) { print_to_log("Error: SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) failed."); } } if (SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) != 0) { print_to_log("Error: SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) failed."); } if (SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) != 0) { print_to_log("Error: SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) failed."); } if (SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) != 0) { print_to_log("Error: SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) failed."); } if (SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) != 0) { print_to_log("Error: SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) failed."); } } 

Three times the code! Of course, I went too far with all the checks, but this is just an example for you to understand what I mean. Maybe someone had the same problem? Tell us how you solved it. Only C language features are interested. Thank you in advance!

  • one
    the same macros are possible, which will unfold in the same myths - Grundy
  • one
    You can make wrapper functions - Vladimir Gamalyan
  • Grundy, so all the checks will remain. Or am I misunderstanding something? Maybe write the code? - eanmos
  • one
    @Eanmos, in order for the notification to come in front of a nickname, you need to set it @ otherwise the user simply will not see what they have answered - Grundy

2 answers 2

One option is to wrap the SDL functions in its own, which will include checking / outputting the log, for example:

 int SDL_GL_SetAttribute_Check(SDL_GLattr attr, int value, const char* hint) { int ret = SDL_GL_SetAttribute(attr, value); if (ret) { print_to_log("SDL_GL_SetAttribute failed"); print_to_log(hint); } return ret; } 

Call (the third argument is a string that can give a hint about the location of the error):

 SDL_GL_SetAttribute_Check(SDL_GL_RED_SIZE, 8, "SDL_GL_RED_SIZE, 8"); 

Alternatively, use macros:

 #define LOG_IF(EXP) do { if (EXP) print_to_log("Error: " #EXP " failed."); } while (0) 

We use:

 LOG_IF(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8)); 

Here, in the event of an error, the function call string used in the macro argument will be displayed:

 Error: SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) failed. 

The macro version is more versatile, since can take any function.

  • 2
    You can also add macro variables __FILE__, __LINE__, __FUNCTION__ to the macro to more precisely locate the error - avp

Well, there are two options:

  1. After putting the program into operation, you hide and will never be connected to the process of "accompanying" your program. The toga "if (RetCode! = 0)" is not necessary to write. :-)
  2. You will have to accompany your program. Then, in order to preserve your own mental health, I strongly recommend that you write all these "if" after each function that returns an error code.

Only two tips:

  • Instead of "print_to_log" use the STANDARD "syslog". Never, under any circumstances, error messages should be issued to the console!
  • After issuing an error message, be sure to put "exit (-1);"
  • "After issuing an error message, be sure to put" exit (-1); ", and if after the error you do not need to close the application? After all, not all errors are fatal. - eanmos
  • "Instead of" print_to_log "use the STANDARD" syslog ". Never, under any circumstances, error messages should not be issued to the console!", And who told you that print_to_log generally displays a message to the console? There is no such function in my project at all. I wrote it for example. Sorry if I misled) - eanmos
  • not all errors are fatal - Only I / O errors can be non-fatal. There is a chance that when you repeat the operation in / in it will end normally. Believe me, any other mistakes are fatal! Fatal in the sense that when the author of the program tries to correct the situation, he enters the field of ASSUMPTIONS. And this leads to any completely unpredictable consequences. Man proposes, and God disposes. Remember? :-) - Sergey
  • What did you say that print_to_log generally prints a message to the console? Its name. Most of the programs that programmers write are demons (in Windows - services) that have no connection with the console at all. And an attempt to enter a console output from such programs often leads to very strange results :-) - Sergey
  • if after all the errors caused an exit , we would not have booted any OS with you. Very rare cases when the OS is loaded without a single error. Look on the Internet, how many people have non-fatal errors, the same ACPII Probe failed :-). - eanmos