Why use errno at all?

I am a Cs student at Technion, I just found out about the errno variable and c-style func. call. This makes me wonder if cyscame uses registers to return a value, why should anyone use "errno" at all?

+4
source share
4 answers

The main reason for using errno is to provide additional error information.

This is especially useful in situations where most (or even all) of the possible return values ​​of a function are actually valid return values.

Consider the fopen() function, which returns a pointer to FILE . Each possible return value is also a valid return value, except for NULL . Therefore fopen() returns NULL on error. But then you cannot say what exactly caused the function to crash. Therefore, fopen() uses errno to indicate the exact error condition, that is, the file does not exist, or you do not have permission to read it, or the system does not have memory or something else.

You can think of errno as a global variable (which it was until threads became popular). Currently, errno usually a macro that reverses a function call that returns an error condition. But this is just a way to implement global variables depending on the flow.

errno alternatives are less convenient:

You can provide a function with a pointer to int , and the function can save its error condition there. strtod() is a good example of this technique. But this makes the API more complex and therefore less desirable. In addition, it forces the programmer to define a new int , which is annoying if you care if the function does not work.

In languages ​​that allow more than one return value (and do not contain exceptions), two values ​​are usually returned: one for the actual result, and the other for the error condition. In languages ​​such as "Go," you see the following code:

 result, ok = foo(); if (ok) { // handle error denoted by "ok" } 

Do not trust people who claim that errno is an β€œold” technique and therefore should be avoided. The machine you are programming is much older than errno or even C, and no one ever complained about it.

+8
source

The C library design was made long ago, at the same time as the early Unix. Using a separate error code is not an unusual pattern (Win32 has a similar GetLastError ()). And it has superficial advantages.

If you decide that you want the function class to have a return value that is commonly used, you cannot easily use this to return errors. For example, imagine a hypothetical API

 mytime_t t = get_current_time(); 

The general use of this API is time. But perhaps in some cases a crash may occur and you will receive detailed error information from errno. This makes the API code a little easier to read and write than if you were talking

 mytime_t t=0; errno_t e = get_current_time(&t); 

So superficially, errno-type systems are attractive. However, separating the error state from the actual function call leads to many problems. Modern environments make errno_t a per-thread variable (eliminating the most obvious source of problems), but you still run into the problem, what if you do

 mytime_t t = get_current_time(); mysize_t s = get_window_size(); 

then you destroy errno from the first function unnoticed. This becomes even more complicated when the code can work in error paths or where one function is implemented from the point of view of others. The storage and restoration of errno values ​​is guaranteed. I believe that it’s pretty well accepted now that such systems are fragile and undesirable.

Many people use exceptions that carry errors outside the explicit parameter / return set (many C ++ programmers make this choice). People working in language-free languages ​​or environments tend to bite a bullet and reserve the return value for an error and always provide output via parameters (COM makes this choice with HRESULT).

+5
source

The best example I can come up with is the stdio fopen function, which returns NULL on failure and the only way to find out why this failed is through errno and / or perror.

There should be other examples. This is exactly what has arisen at the present time.

+2
source

errno is a tricky thing as it is a historical interface that probably no one would create like this these days. In addition, in most systems it now only looks like a variable, this is not one. It is usually implemented as a macro that hides a function call, and this function call returns an error condition that depends on the stream.

+2
source

All Articles