|
http://www.lysator.liu.se/c/rat/d1.html#4-1-3<errno.h> is a header invented to encapsulate the error handling mechanism used by many of the library routines in math.h and strlib.h. [Footnote: In earlier drafts of the Standard, errno and related macros were defined in <stddef.h>. When the Committee decided that the other definitions in this header were of such general utility that they should be required even in freestanding environments, it created <errno.h>.]
The error reporting machinery centered about the setting of errno is generally regarded with tolerance at best. It requires a ``pathological coupling'' between library functions and makes use of a static writable memory cell, which interferes with the construction of shareable libraries. Nevertheless, the Committee preferred to standardize this existing, however deficient, machinery rather than invent something more ambitious.
The definition of errno as an lvalue macro grants implementors the license to expand it to something like *__errno_addr(), where the function returns a pointer to the (current) modifiable copy of errno.
And from the C99 Standard (?) The C99 standard Section 7.5 <errno.h>"3 The value of errno is zero at program startup, but is never set to zero by any library function.170) The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard."
"170) Thus, a program that uses errno for error checking should set it to zero before a library function call, then inspect it before a subsequent library function call. Of course, a library function can save the value of errno on entry and then set it to zero, as long as the original value is restored if errno's value is still zero just before the return."
I just know that some of the string functions do not return 0 or -1 as you mentioned - so that method cannot be used in that situation. And I see from these comments that it would be a very bad idea to try to use errno in functions I write - but they are needed with certain library functions - albeit not loved by all.
Regards Vern At 11:59 PM 11/19/2006, you wrote:
On 20/11/2006, at 3:16 PM, Vernon Hamberg wrote: > Why? Because it is the generally accepted recommendation - as stated > by Jon Paris as follows in his "Who Knew You Could..." redbook: 1) But it's not a generally recommended practice in C programming and errno is a C run-time attribute 2) Jon wasn't the only author of that Red Book so it's possible this recommendation came from a different source. 3) Even if Jon wrote the quote below I think he is wrong for recommending it. My view is the same as Scott's on this one. If you want to quote someone who knows what he's talking about** then you'd be hard-pressed to find a more authoritative source than W. Richard Stevens. From "Advanced Programming in the Unix Environment"""There are two rules to be aware of with respect to errno. First, itsvalue is never cleared by a routine if an error does not occur. Therefore, we should examine its value only when the return value from a function indicates that an error occurred. Second, the value of errno is never set to 0 by any of the functions, and none of the constants defined in <errno.h> have a value of 0." To me that says that testing errno for a non-zero value is valid but testing it for 0 is not valid. ** Not suggesting that Jon doesn't know what he's talking about but in this particular case, if he is the originator of the quote to which you refer, then he's wrong. > > The error code is made available by the GetErrNo() function, which is a > remapped __error() C function. The GetErrNo() function gets access to > the ErrNo > variable through a pointer. The ErrNo variable contains the error > code. Before > issuing any function that returns an error code, the ErrNo variable > should be > cleared. However, it is possible only after the GetErrNo() function > was performed. > If the error code is not cleared before the function is entered, the > resulting error > code may be false. Only if you write code that checks errno without first checking the function return value to see if errno SHOULD be checked. If you do that then you are wrong. > > errno - as I know you know - is a global variable used by everything > - it is not changed if not error occurs, so setting it to 0 just > before a function that might set it and then checking it after is how > I understand doing this. You can't rely on the function you call AFTER setting errno to zero to be the only thing that may change it. You and others are suggesting (or defending): set erro no to zero call OS function X() check errno is still zero However you have no way of knowing what other functions are called by X(). It may call Y() which might fail and set errno. X() might handle this condition and therefore return successfully leaving errno to whatever Y() set it. Checking errno to determine success or failure in this case is obviously flawed. A similar situation can happen in application code that wraps multiple OS functions into one higher-level function--especially if it handles the error condition. Unless you have the practice of always resetting errno to zero after testing it you run the risk of getting a false error condition. Note that IF you did this sort of thing you would be flouting existing convention regarding errno. Because you CANNOT know what happens to errno after you call an OS function the only thing you can do is check the function return value for an error indication PRIOR to testing errno. > > Not all functions return an error code - an example is StrToD - it > returns a float value - it is commonly used to test whether a string > is numeric - the only reliable test for errors is to set errno - the > global variable - before calling StrToD and then checking it after the > call. strtod() is not a very reliable way of determining if a string is numeric. Like most of these C conversion functions it makes a best effort and never actually fails. It simply stops checking when it finds a character that is not a valid digit. strtod() does have two pseudo error conditions: a) overflow b) underflow Overflow returns HUGE_VAL. Underflow returns zero. In these cases errno might be set to ERANGE but not always. So checking result for +HUGE_VAL or -HUGE_VAL or zero might indicate an error. HUGE_VAL is probably an error but zero is a valid floating point value so might not indicate an error. I've had strtod() return zero in an underflow condition but errno has remained at zero. No way to tell whether zero is the correct result. Given that errno is not always set by this function it's not reliable to rely on it. If you do use strtod() to check for a numeric string it is the endptr string that must be checked, not the return value. Because the return value is the only thing that MIGHT be affected by errno it follows that errno can't be reliably used on its own either and certainly not to determine whether a string is numeric. > > Tightly coupling the setting and checking will not cause problems > with other functions, as far as I know. See suggested example above. Regards, Simon Coulter. -------------------------------------------------------------------- FlyByNight Software AS/400 Technical Specialists http://www.flybynight.com.au/ Phone: +61 3 9419 0175 Mobile: +61 0411 091 400 /"\ Fax: +61 3 9419 0175 \ / X ASCII Ribbon campaign against HTML E-Mail / \ -------------------------------------------------------------------- -- This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options, visit: http://lists.midrange.com/mailman/listinfo/rpg400-l or email: RPG400-L-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/rpg400-l.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.