× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Simon - this gets more interesting - here is a bit from, I believe, a C standards committee:

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, its
value 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 thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

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.