I'm writing a module which exports an interface similar to send and recv.
Since those functions are supposed to return respectively the number of sent and received bytes, I cannot do proper error management as I would do normally (i.e. using enumeratives and returning mnemonic values).
In a situation like this should I set errno as the standard library does? If so, since errno is thread specific, is there a particular way of writing on it, or can I simply assign a value to it?
Edit: experimenting it I noticed that setting errno by assignment is working. Still: is this safe and portable for any system?
This is a bit old, but errno - manual section 3 says that you can directly assign to it, even though it is a macro, and it will be thread local
Not only can you set errno, in many cases you should set errno. When calling some library functions you can only reliably detect an error if you first set errno to zero. See strtol for an example.
From the POSIX specification of strtol:
[CX] [Option Start] The strtol() function shall not change the setting of errno if successful.
Since 0, {LONG_MIN} or {LLONG_MIN}, and {LONG_MAX} or {LLONG_MAX} are returned on error and are also valid returns on success, an application wishing to check for error situations should set errno to 0, then call strtol() or strtoll(), then check errno. [Option End]
Actually, you probably can do "proper" (as you put it) error management since you return an int.
Just use non-negative values for the number of bytes read or written and negative values for error codes. You don't have to limit yourself to -1:
enum myerrors {
ERR_NO_MEMORY = -1,
ERR_BAD_ARGS = -2,
ERR_CPU_EXPLODED = -3,
// and so on
};
However, setting errno in the fashion you want is valid. The standard states that errno expands to a modifiable lvalue, meaning you can set it. From C1x/n1425, 7.5 Errors <errno.h>:
... and errno which expands to a modifiable lvalue that has type int, the value of which is set to a positive error number by several library functions.
You can just assign a value to errno, but keep in mind that there are other ways to signal an error which, depending on your situation, may be more suitable:
Do not return the number of bytes read, but instead have an output parameter with type int * (or size_t * or whatever you use). You can then return an error code.
Assuming that your return type is a signed type and that a negative sent or received amount of bytes does not make sense, use negative values to signal the respective error conditions.
Yes, you can assign to it, and yes, the assignment will be thread-safe. See Is errno thread-safe?
From: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm
The only portable values for errno are EDOM and ERANGE
So that answers your portability question.
Related
I previously read that 0 in C-Language refers to false while 1 is true.
And have noticed that the main function returns 0 but why is that? in case all of my code ran successfully it should return true (1).
Another related question, I still can't understand who can use the returnable value? since no other function called the main function inside my program so nothing can know if my program ran well or not.
I am a little bit confused.
Your logic would make sense if the return value of main were interpreted as a Boolean value, but it isn't. Returning from the initial call to main is like calling the exit function: It reports a termination status to the system you're running on.
Standard C specifies 3 portable exit statuses:
0, indicating success
EXIT_SUCCESS, also indicating success
EXIT_FAILURE, indicating failure
(The last two are macros defined in <stdlib.h>.)
On Unix, any 8-bit value (0 .. 255) is allowed. All non-zero values are interpreted as error codes. There is no universal convention for what any given number means, just that 0 represents success and anything else some kind of failure.
As for who can use the return value: On Unix, a parent process can use wait or waitpid to get the exit status of a terminated child.
In the C standard library, functions that perform an action generally don't return a true/false status. (Tests such as islower or isdigit do, but they don't have any other effects.) For example, remove (which deletes a file) returns 0 on success and -1 on error. This is also a common pattern with Unix system calls. For exmple, open returns a file descriptor (a non-negative integer) on success and -1 on error.
It's essentially what #Brandon already said in the comments.
main is supposed to return the exit/error code of the program. In the Unix convention, 0 is used to indicate no error (the error value is "false"). And then positive values are used for indicating that there is an error and what error it was.
It's really just about the kind of question you ask a program when it finish.
Case 1:
Did you fail?
Case 2:
Did you pass?
In the first case a "good program" will return false (aka zero)
In the second case a "good program" will return true (aka non-zero).
Consensus is to use Case 1, i.e. "Did you fail?". Therefore a non-failing program returns zero to say "I did not fail".
The benefit of this approach is that non-zero values can be used to expressed different kind of failures while zero is alway "no failure"
There's a difference between what the C language considers true (non-zero) or false (zero) and what value(s) the operating system uses to indicate a normal program termination.
To be strictly correct, C programs should exit with a code of either EXIT_SUCCESS for normal program termination or EXIT_FAILURE for abnormal termination. EXIT_SUCCESS will map to whatever code the underlying platform uses to indicate success, which may or may not be 0.
Most functions that returns a handle, such as OpenProcess, OpenFile, OpenThread, FindWindow, etc, return 0 upon failure. I understand that return an invalid result to indicate failure is a good practice. However, if windows choose -1 to be the INVALID_HANDLE_VALUE, why don't these functions return -1 upon failure?
There are many conjectures you can make, but yes the reasons are historical and due to compatibility in the process of porting old 16bits code to newer one.
Some functions originally returned -1 when failing, in the respect of C habit to return negative values on failure.
Moving to new 32bits versions, for the reason of compatibility mentioned above, lead to the creation of INVALID_HANDLE_VALUE equated to -1.
But because the handles sometimes were real pointers, and for the simplicity of comparison for NULL value many new functions were designed to return NULL on failure.
One interesting point is that INVALID_HANDLE_VALUE happens to be numerically equal to the pseudohandle returned by GetCurrentProcess(). So using an invalid handle in some functions could lead to valid results or terrible deadlocks as in the case of INVALID_HANDLE_VALUE used in a call to WaitForSingleObject. This will lead to an endless wait for the current process.
You can find the whole story, told from the authors, here https://blogs.msdn.microsoft.com/oldnewthing/20040302-00/?p=40443
I'm currently writing a C function that return a time_t value but I need to manage error cases (because this function uses I/O functions) too.
Is it correct to use (time_t) -1 as an error indicator?
Using (time_t)-1 is already used by time() function to report a failure so does not seem an unreasonable choice:
Current calendar time encoded as time_t object on success, (time_t)(-1) on error. If the argument is not NULL, the return value is equal to the value stored in the object pointed to by the argument.
However, if it is necessary for the caller to differentiate between a time related failure or an IO related failure (or specific IO failures) you may consider adding a status type argument to your function that can be used to return additional information about the failure.
The time function itself returns (time_t) -1 on error, so using (time_t) -1 should work just fine.
Yes, time_t is signed.
So it perfectly ok to make the function return -1 to indicate an error.
Anyway, you should make sure, that from the logic of your API you never need to return any negative time differences, as time_t is signed to be able to express (also?) differences.
Update:
This is guaranteed on POSIX systems only. An even there signed is in misleading, as http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/types.h.html defines time_t to be an int or a real-floating type.
So on POSIX conforming systems time_t is able to carry negative values.
The value (time_t)-1 indicates 1969-12-31T23:59:59+00:00, the second before The (Unix) Epoch.
It is returned by some of the Standard C time functions, which is a confounded nuisance if you might need to work with historical times and need to distinguish between an actual error and the occasional occurrence of the second before The Epoch. You'd do better with the (hypothetical) TIME_T_MAX or TIME_T_MIN values — the maximum or minimum possible value of time_t. (But be aware that there's only 25 years or so left before the upper limit for a signed 32-bit time_t occurs — in January 2038.)
This question already has answers here:
What is a good general approach for deciding return values in C?
(8 answers)
Closed 8 years ago.
I was wondering whether there are any pre-agreed values, coming from the old days of C language, that reflect tha function execution threw exception/terminated abruptly/failed for any reason? Is this value 0, or -1 or is it completely up to you and no standards exist?
Functions that return pointers usually return NULL to indicate failure (e.g. malloc).
Most POSIX functions return 0 on success, and non-zero on failure. If they need to return a non-zero value as part of normal operation, they often return a negative value on failure.
But this is all just convention.
One common convention is to return an invalid value, whatever it is. For instance, functions returning lengths may return -1 on failure.
General purpose error codes tend to be 0 or NULL to mimick malloc's behavior. POSIX, on the other hand, uses the inverse convention.
Be sure to get accustomed to errno for more "advanced" error checking. Many standard library routines put an error code there to be checked on failure.
Another simple example:
if (wpa_s->mlme.ssid_len == 0)
return -EINVAL;
Why the unary minus? Is this (usually) done for functions that return >0 on success and <(=)0 on failure, or is there some other reason?
First, this isn't really a C thing. You're looking at a function that is written in C for some purpose. The same conventions could be used in any language.
Back in my old Unix days, there was something of a convention that 0 meant success, a positive number meant minor problems, and a negative number meant some sort of failure. Therefore, there was also a sort of convention of if (foo() >= 0) { /* success of a sort */ }.
This was doubtless related to Unix process return codes, where 0 was success.
That's basically the reasons. Lots of functions have lots of "good" positive results, so that leaves the negative values for error codes.
C / POSIX error codes are a bit "historically grown," so there's not much sense in trying to attribute too much rhyme or reason to them.
Many more modern languages throw exceptions for errors so that they don't have to hijack part of their possible response range for error codes. Of course there are trade-offs either way.
Your understanding is broadly correct. The obvious interpretation is the right one.
The standard convention is slightly different than your formula, however.
In Unix, a program that exits with 0 status tests as true or success to CLI-level utilities like the shell. In the library, -1 is usually an error return.
This leads to a general paradigm where >= 0 means good and < 0 means error. None of this is set in stone.
BTW, this might be classified as the sentinel pattern and you could call it a sentinel return. It's actually a combination of a sentinel "value" and an error code, and it's easier to type and easier to make thread-safe than returning an error code in one place and a sentinel value for error in another.
Wikipedia reports that a sentinel value is used to terminate a loop, but I would think that a function return would be a far more common instance. No one is precisely in charge of these definitions.
From an optimization perspective, using negative numbers allows Unix-based kernels to check for an error code using only one comparison instead of two.
Functions in the kernel frequently return error codes in place of pointers. This means that the error codes can't overlap with valid pointer addresses, so they'd basically have to be either the lowest unsigned values (>= 0) or the highest ones (<= unsigned max).
Checking pointer values for NULL and for error codes are extremely common operations, so it makes sense to optimize them.
Typically the bottom values < 0x8000 are NULL and the top values are error codes (remember that -1 is stored as 0xff...ff, the maximum possible unsigned value).
This means that you can use one comparison to check for each:
NULL if x <= 0x8000 (true for 0 to 0x8000)
ERRNO if x >= (unsigned long)(-MAX_ERRNO) (true for -1 to -MAX_ERRNO)
You can see this happening in Linux's err.h file.