0

Function return types are useful for returning values that indicate if the function did what it was supposed to do.

However if error handling is done within the function (for example fprintf(stderr, errormessage) and exit(EXIT_FAILURE)) that means one could define a function with the void return type instead.

So my question is: is it bad practice in C to have a program with multiple functions with void return types while handling errors in the way stated above in contrast to returning a number?

I ask because I am writing a program and noticed my header files look like this and each function uses printing to stderr and exit():

void function1();
void function2();
void function3();
void function4();
void function5();
void function6();
void function7();
void function8();
void function9();
  • As with most things in computing the answer is "it depends". Calling `exit` may or may not be the right approach depending on what those functions do, what the actual errors are, what actual recovery can be done, etc. So the question isn't really answerable without actual specifics. And even with specifics different people may have different opinions. – kaylum Jul 21 '22 at 01:18
  • You should define prototypes in your headers — and `void function5();` does not define a prototype. It declares the function, but it says nothing useful about the parameters it takes. The only modestly useful information is that the function does not take variadic arguments, which must be declared via `, ...` at the the end of the prototype. If the functions take no arguments, use `void function5(void);`. But if they take no arguments, they must be using global variables exclusively, which is appalling style. Your functions should take arguments! A few don't need to, but most should. – Jonathan Leffler Jul 21 '22 at 05:20
  • so ```void function5()``` is a incorrect function prototype ? so instead i should also define any arguments the function takes (or use ```void``` if it takes none)? – programme3219873 Jul 21 '22 at 10:01

2 Answers2

1

In general, returning void isn't bad if your errors are handled internally. The point is for all errors to be handled somewhere. Error codes are for the things that the caller needs to handle.

Speaking to your particular case, terminating the entire program when an error occurs isn't really error handling. It's just an extremely fragile program. You're not giving the rest of your program a chance to clean up after itself, so you can end up with leaked resources, things left in unsafe states, etc. The only time an error should terminate your program is if there's no possible way to handle it gracefully (and there almost always is). The error "handling" technique you describe might be okay for very short toy programs but for anything beyond that, you need to write real error handling code.

bta
  • 43,959
  • 6
  • 69
  • 99
-1

That depends on how many exceptions you will need to handle. But I would highly recommend you to use the errno variable which will always store the number of the last error. It will return -1 if something went wrong, and 0 if not. You can easily use it after invoking some function and/or system calls, it will automatically set the value according to the output/value of the last function that was invoked. You can also check which type/the name of the error that was thrown, for this, the errno.h header offers a huge collection of errors names that you can combine with your project requirements. For example, after trying to read a file, you can check if some error occurred and which type of error. Check the code bellow.

#include<errno.h> //you need it.
#include<stdio.h>


int main(){
    FILE *fd;
    if (fopen("/myfile.itsextension", someflaghere){
         if (errno ==  ENOENT){
            // ENOENT stands for: No such file or directory
           //do something here if it is the error
         }
         //if it is something else
         errno("Error:"); it output in the console Error: some message according to the error that occurred.
    }
}

You can check more about errno at the manpage website.

If you really need to create your own errors handler, just make sure you create it as a header.

I hope it helps you.

  • 2
    Using errno for non system errors? Not something I've ever seen done. It could screw up things like perror that use errno to index into sys_errlist. If you are using errno like this you should pick standard errnos with a meaning close to your status. – John3136 Jul 21 '22 at 01:56
  • You are right, thanks! perror should be suitable. – António Pedro Jul 21 '22 at 18:58
  • Though the answer is clear and contains a helpful example, I think you should mention that this is a bit like taking a shortcut. `errno` is a variable set internally by the C standard library that the callers use for error management. Setting the value from outside the standard library might cause side-effects to the rest of the program. We could suggest implementing our own `static int user_error` in OP's use-case used for errors thrown in his application. – Tristan Dubé Jul 26 '22 at 01:43