Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #3162 > unrolled thread
| Started by | pozz <pozzugno@gmail.com> |
|---|---|
| First post | 2011-05-03 01:31 -0700 |
| Last post | 2011-05-03 12:09 -0700 |
| Articles | 20 on this page of 30 — 19 participants |
Back to article view | Back to comp.lang.c
Return value for error pozz <pozzugno@gmail.com> - 2011-05-03 01:31 -0700
Re: Return value for error jacob navia <jacob@spamsink.net> - 2011-05-03 10:46 +0200
Re: Return value for error Ike Naar <ike@otaku.freeshell.org> - 2011-05-03 09:04 +0000
Re: Return value for error Ian Collins <ian-news@hotmail.com> - 2011-05-03 21:19 +1200
Re: Return value for error James Kuyper <jameskuyper@verizon.net> - 2011-05-03 06:26 -0400
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-03 12:03 -0700
Re: Return value for error "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-05-04 05:15 -0700
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-04 08:26 -0700
Re: Return value for error "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-05-04 17:08 -0700
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-04 17:54 -0700
Re: Return value for error "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-05-05 12:03 -0700
Re: Return value for error James Dow Allen <jdallen2000@yahoo.com> - 2011-05-03 03:45 -0700
Re: Return value for error Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-05-03 20:50 +0000
Re: Return value for error pete <pfiland@mindspring.com> - 2011-05-03 07:50 -0400
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-03 12:04 -0700
Re: Return value for error Martin Ambuhl <mambuhl@earthlink.net> - 2011-05-03 07:59 -0400
Re: Return value for error Mark Storkamp <mstorkamp@yahoo.com> - 2011-05-03 08:46 -0500
Re: Return value for error Stephen Sprunk <stephen@sprunk.org> - 2011-05-03 10:13 -0500
Re: Return value for error William Ahern <william@wilbur.25thandClement.com> - 2011-05-03 13:08 -0700
Re: Return value for error Kenneth Brody <kenbrody@spamcop.net> - 2011-05-03 13:23 -0400
Re: Return value for error Peter Nilsson <airia@acay.com.au> - 2011-05-03 16:01 -0700
Re: Return value for error Nobody <nobody@nowhere.com> - 2011-05-05 07:21 +0100
Re: Return value for error Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-05 15:13 +0100
Re: Return value for error Nobody <nobody@nowhere.com> - 2011-05-06 03:51 +0100
Re: Return value for error James Kuyper <jameskuyper@verizon.net> - 2011-05-05 23:38 -0400
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-05 08:44 -0700
Re: Return value for error Seebs <usenet-nospam@seebs.net> - 2011-05-05 20:49 +0000
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-05 14:10 -0700
Re: Return value for error Seebs <usenet-nospam@seebs.net> - 2011-05-06 00:26 +0000
Re: Return value for error Keith Thompson <kst-u@mib.org> - 2011-05-03 12:09 -0700
Page 1 of 2 [1] 2 Next page →
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2011-05-03 01:31 -0700 |
| Subject | Return value for error |
| Message-ID | <e63ceea9-301d-4b90-9495-4e2a8085fae5@x1g2000yqb.googlegroups.com> |
A very simple question. What do you use as the return value of a
function for error/ok results?
I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
for errors.
If !=0 is ok, I can write:
if (myfunction()) printf("OK\n");
but I have only one error code (0), while, in some cases, it could be
useful to have more informations about the type of error.
If !=0 is error I can have several error codes, but I have to write
if (!myfuction()) printf("OK\n");
that apparently seems myfunction has not terminated with success.
Another strategy is to define custom error code:
#define ERROR_OK 0
#define ERROR_UNDEFINED 1
#define ERROR_WRONGVALUE 2
and so on, and always write:
if (myfuction() == ERROR_OK) printf("OK\n");
[toc] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-05-03 10:46 +0200 |
| Message-ID | <ipofdd$e5k$1@speranza.aioe.org> |
| In reply to | #3162 |
Le 03/05/11 10:31, pozz a écrit :
> A very simple question. What do you use as the return value of a
> function for error/ok results?
> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> for errors.
>
> If !=0 is ok, I can write:
>
> if (myfunction()) printf("OK\n");
>
> but I have only one error code (0), while, in some cases, it could be
> useful to have more informations about the type of error.
Yes... That is the reason that option is not really useful.
>
> If !=0 is error I can have several error codes, but I have to write
>
> if (!myfuction()) printf("OK\n");
>
> that apparently seems myfunction has not terminated with success.
>
I would recommend
if (myfunction() == SUCCESS)
where SUCCESS is zero
> Another strategy is to define custom error code:
>
> #define ERROR_OK 0
> #define ERROR_UNDEFINED 1
> #define ERROR_WRONGVALUE 2
>
> and so on, and always write:
>
> if (myfuction() == ERROR_OK) printf("OK\n");
The problem with "ERROR_OK" is that it is contradictory: An "OK error" ?
In the C containers library I decided (after much pondering) that:
Positive value: No error
Negative value: error code
Zero: Warning but OK.
For instance a function like POP(container) will return
< 0 if container == NULL. This is a hard error.
Zero: container was empty. Maybe this isn't an error.
>0 one element was popped. This means everything is OK.
if (Pop(container) < 0) {
// error handling
}
Note that you can code other useful information in positive values.
You could return the number of elements still remaining in the stack
for instance.
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@otaku.freeshell.org> |
|---|---|
| Date | 2011-05-03 09:04 +0000 |
| Message-ID | <slrn3vfsirvh8s.dl3.ike@otaku.freeshell.org> |
| In reply to | #3162 |
On 2011-05-03, pozz <pozzugno@gmail.com> wrote:
> A very simple question. What do you use as the return value of a
> function for error/ok results?
> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> for errors.
>
> If !=0 is ok, I can write:
>
> if (myfunction()) printf("OK\n");
>
> but I have only one error code (0), while, in some cases, it could be
> useful to have more informations about the type of error.
>
> If !=0 is error I can have several error codes, but I have to write
>
> if (!myfuction()) printf("OK\n");
>
> that apparently seems myfunction has not terminated with success.
>
> Another strategy is to define custom error code:
>
> #define ERROR_OK 0
> #define ERROR_UNDEFINED 1
> #define ERROR_WRONGVALUE 2
>
> and so on, and always write:
>
> if (myfuction() == ERROR_OK) printf("OK\n");
Another improvement would be to drop the ``ERROR'' prefix from
the constants (``ERROR_OK'' is a contradictio in terminis, isn't it?)
and replace it with a prefix that indicates that the constant has to do
with a particular function.
This helps if your program has several functions that follow the same
strategy.
#define FROBOZZ_OK 0
#define FROBOZZ_UNDEFINED 1
#define FROBOZZ_WRONGVALUE 2
#define WHACK_OK 0
#define WHACK_UNWHACKABLE 1
#define WHACK_ALREADYWHACKED 2
if (frobozz() == FROBOZZ_OK) printf("OK\n");
if (whack() == WHACK_OK) printf("OK\n");
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-03 21:19 +1200 |
| Message-ID | <929vk4Fj03U11@mid.individual.net> |
| In reply to | #3164 |
On 05/ 3/11 09:04 PM, Ike Naar wrote:
> On 2011-05-03, pozz<pozzugno@gmail.com> wrote:
>> A very simple question. What do you use as the return value of a
>> function for error/ok results?
>> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
>> for errors.
>>
>> If !=0 is ok, I can write:
>>
>> if (myfunction()) printf("OK\n");
>>
>> but I have only one error code (0), while, in some cases, it could be
>> useful to have more informations about the type of error.
>>
>> If !=0 is error I can have several error codes, but I have to write
>>
>> if (!myfuction()) printf("OK\n");
>>
>> that apparently seems myfunction has not terminated with success.
>>
>> Another strategy is to define custom error code:
>>
>> #define ERROR_OK 0
>> #define ERROR_UNDEFINED 1
>> #define ERROR_WRONGVALUE 2
>>
>> and so on, and always write:
>>
>> if (myfuction() == ERROR_OK) printf("OK\n");
>
> Another improvement would be to drop the ``ERROR'' prefix from
> the constants (``ERROR_OK'' is a contradictio in terminis, isn't it?)
> and replace it with a prefix that indicates that the constant has to do
> with a particular function.
> This helps if your program has several functions that follow the same
> strategy.
>
> #define FROBOZZ_OK 0
> #define FROBOZZ_UNDEFINED 1
> #define FROBOZZ_WRONGVALUE 2
I prefer an enum to #defines. It's more debugger friendly, less typing
and gives you a type to return.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-05-03 06:26 -0400 |
| Message-ID | <ipol8c$ohd$1@dont-email.me> |
| In reply to | #3162 |
On 05/03/2011 04:31 AM, pozz wrote:
> A very simple question. What do you use as the return value of a
> function for error/ok results?
> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> for errors.
>
> If !=0 is ok, I can write:
>
> if (myfunction()) printf("OK\n");
This is a perfectly reasonable approach, but when you use it, one of the
most important things is to make sure to name the function so that it
can be read as a question, and give it a non-zero value if the answer to
that question is "yes". Example from the C standard library: isalpha().
However, there's also lots of functions in the C standard library which
violate this rule; for instance, fseek().
If you can't think of a name for the function which would make this
work, then using this approach is probably not appropriate.
...
> Another strategy is to define custom error code:
>
> #define ERROR_OK 0
> #define ERROR_UNDEFINED 1
> #define ERROR_WRONGVALUE 2
>
> and so on, and always write:
>
> if (myfuction() == ERROR_OK) printf("OK\n");
If your code returns multiple different error codes, then somewhere you
should have a call to the function that actually does different things,
depending upon which error code is returned; a switch() is usually the
best way to do this. You can also have calls that don't make a
distinction; but if there aren't any calls to the function which do make
the distinction, then you don't really need to distinguish different
error conditions.
I'm guilty of violating that rule in my own code; but my intention is
that test drivers for the called routine will check which error code is
returned, even if the actual delivered program does not.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-05-03 12:03 -0700 |
| Message-ID | <lnaaf3vc77.fsf@nuthaus.mib.org> |
| In reply to | #3167 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 05/03/2011 04:31 AM, pozz wrote:
>> A very simple question. What do you use as the return value of a
>> function for error/ok results?
>> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
>> for errors.
>>
>> If !=0 is ok, I can write:
>>
>> if (myfunction()) printf("OK\n");
>
> This is a perfectly reasonable approach, but when you use it, one of the
> most important things is to make sure to name the function so that it
> can be read as a question, and give it a non-zero value if the answer to
> that question is "yes". Example from the C standard library: isalpha().
Right. The important distinction here is that the result of isalpha()
is purely a yes/no result, *not* a success/failure result. If isalpha()
could tell you either
Yes, that's an alphabetic character
or
No, that's not an alphabetic character
or
Oops, I can't tell what that is
the it would need a different interface. In fact, none of the is*()
functions have any way to indicate failure.
> However, there's also lots of functions in the C standard library which
> violate this rule; for instance, fseek().
I wouldn't say fseek() violates the rule, it just follows a different
one. It attempts to perform an action (seeking to the specified
position) and returns a result indicating either that it succeeded, or
that it failed. The common convention is to use 0 for success, non-0
for failure. (It doesn't use different non-0 values to denote different
kinds of failure.)
> If you can't think of a name for the function which would make this
> work, then using this approach is probably not appropriate.
Agreed. But even if the function answers a yes/no question, you still
have to think about cases where the question can't be answered. Most
yes/no functions in the standard library don't have ways to indicate
errors (see is*(), feof(), ferror()).
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "Kleuskes & Moos" <kleuske@xs4all.nl> |
|---|---|
| Date | 2011-05-04 05:15 -0700 |
| Message-ID | <c24039e1-19f0-41f5-8b24-4a645ed11004@24g2000yqk.googlegroups.com> |
| In reply to | #3186 |
On May 3, 9:03 pm, Keith Thompson <ks...@mib.org> wrote:
> James Kuyper <jameskuy...@verizon.net> writes:
> > On 05/03/2011 04:31 AM, pozz wrote:
> >> A very simple question. What do you use as the return value of a
> >> function for error/ok results?
> >> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> >> for errors.
>
> >> If !=0 is ok, I can write:
>
> >> if (myfunction()) printf("OK\n");
>
> > This is a perfectly reasonable approach, but when you use it, one of the
> > most important things is to make sure to name the function so that it
> > can be read as a question, and give it a non-zero value if the answer to
> > that question is "yes". Example from the C standard library: isalpha().
>
> Right. The important distinction here is that the result of isalpha()
> is purely a yes/no result, *not* a success/failure result. If isalpha()
> could tell you either
> Yes, that's an alphabetic character
> or
> No, that's not an alphabetic character
> or
> Oops, I can't tell what that is
> the it would need a different interface. In fact, none of the is*()
> functions have any way to indicate failure.
Perhaps that's got to do with the fact that they cannot actually fail.
Whatever the input, it's always possible to say wether it codes for an
letter, a number, upper or lower case character or not.
However, for functions that might actually fail, the consideration is
actually an important one.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-05-04 08:26 -0700 |
| Message-ID | <lnoc3itrkz.fsf@nuthaus.mib.org> |
| In reply to | #3225 |
"Kleuskes & Moos" <kleuske@xs4all.nl> writes:
> On May 3, 9:03 pm, Keith Thompson <ks...@mib.org> wrote:
[...]
>> Right. The important distinction here is that the result of isalpha()
>> is purely a yes/no result, *not* a success/failure result. If isalpha()
>> could tell you either
>> Yes, that's an alphabetic character
>> or
>> No, that's not an alphabetic character
>> or
>> Oops, I can't tell what that is
>> the it would need a different interface. In fact, none of the is*()
>> functions have any way to indicate failure.
>
> Perhaps that's got to do with the fact that they cannot actually fail.
> Whatever the input, it's always possible to say wether it codes for an
> letter, a number, upper or lower case character or not.
Well, sort of. The argument of the is*() function is an int,
but its value is required to be representable as an unsigned char
or to be equal to EOF. The standard *could* have specified some
kind of error handling for isalpha(UCHAR_MAX + 1), but instead it
just says the behavior is undefined. Similarly, the behavior of
feof(FILE*(NULL)) is undefined.
The choice was between imposing a small burden on the caller to
avoid passing bad arguments, and making the interface substantially
more inconvenient.
> However, for functions that might actually fail, the consideration is
> actually an important one.
Right. If you want to have a function that returns a yes/no result,
but the caller can't reliably avoid passing invalid arguments,
you might have it return an error code (zero for success, non-zero
for error) and pass the actual result via an int* argument.
(Languages with exception handling generally don't have this problem.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "Kleuskes & Moos" <kleuske@xs4all.nl> |
|---|---|
| Date | 2011-05-04 17:08 -0700 |
| Message-ID | <6a2107db-6e19-41a8-aa82-616cc2caa6aa@c41g2000yqm.googlegroups.com> |
| In reply to | #3231 |
On May 4, 5:26 pm, Keith Thompson <ks...@mib.org> wrote: > "Kleuskes & Moos" <kleu...@xs4all.nl> writes: > > > > > > > > > > > On May 3, 9:03 pm, Keith Thompson <ks...@mib.org> wrote: > [...] > >> Right. The important distinction here is that the result of isalpha() > >> is purely a yes/no result, *not* a success/failure result. If isalpha() > >> could tell you either > >> Yes, that's an alphabetic character > >> or > >> No, that's not an alphabetic character > >> or > >> Oops, I can't tell what that is > >> the it would need a different interface. In fact, none of the is*() > >> functions have any way to indicate failure. > > > Perhaps that's got to do with the fact that they cannot actually fail. > > Whatever the input, it's always possible to say wether it codes for an > > letter, a number, upper or lower case character or not. > > Well, sort of. The argument of the is*() function is an int, > but its value is required to be representable as an unsigned char > or to be equal to EOF. The standard *could* have specified some > kind of error handling for isalpha(UCHAR_MAX + 1), but instead it > just says the behavior is undefined. Similarly, the behavior of > feof(FILE*(NULL)) is undefined. Aye, it could have introduced a check, and it might have ordained array-bounds-checking, too, but the fact of the matter is it doesn't. and it seems aginst the spirit of C, too. Besides, returning false for isalpha(65535) is a very reasonable implementation of that particular bit of undefined behavior and I suspect most compilers will do. > The choice was between imposing a small burden on the caller to > avoid passing bad arguments, and making the interface substantially > more inconvenient. Yup. And the ghost of C demands it's the programmers responsibility. Fortunately C is not Pascal. > > However, for functions that might actually fail, the consideration is > > actually an important one. > > Right. If you want to have a function that returns a yes/no result, > but the caller can't reliably avoid passing invalid arguments, > you might have it return an error code (zero for success, non-zero > for error) and pass the actual result via an int* argument. Ack. > (Languages with exception handling generally don't have this problem.) :) Instead they have other problems. The Law of Conservation of Misery is unrelenting...
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-05-04 17:54 -0700 |
| Message-ID | <lnzkn2rmoz.fsf@nuthaus.mib.org> |
| In reply to | #3240 |
"Kleuskes & Moos" <kleuske@xs4all.nl> writes:
> On May 4, 5:26 pm, Keith Thompson <ks...@mib.org> wrote:
[...]
>> Well, sort of. The argument of the is*() function is an int,
>> but its value is required to be representable as an unsigned char
>> or to be equal to EOF. The standard *could* have specified some
>> kind of error handling for isalpha(UCHAR_MAX + 1), but instead it
>> just says the behavior is undefined. Similarly, the behavior of
>> feof(FILE*(NULL)) is undefined.
>
> Aye, it could have introduced a check, and it might have ordained
> array-bounds-checking, too, but the fact of the matter is it doesn't.
> and it seems aginst the spirit of C, too. Besides, returning false for
> isalpha(65535) is a very reasonable implementation of that particular
> bit of undefined behavior and I suspect most compilers will do.
In my experience, at least some implementations define macros for
the is*() functions, macros that work by indexing into arrays.
isalpha(65535) will go well outside the bounds of the array,
with unpredictable results. (At least one implementation I've
seen defensively allows for small negative arguments, so (signed)
char arguments work as they should, even though the standard doesn't
require them to. But you shouldn't depend on that.)
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "Kleuskes & Moos" <kleuske@xs4all.nl> |
|---|---|
| Date | 2011-05-05 12:03 -0700 |
| Message-ID | <0f08f919-f319-4108-b5ee-e4f7889de06a@s2g2000yql.googlegroups.com> |
| In reply to | #3243 |
On May 5, 2:54 am, Keith Thompson <ks...@mib.org> wrote: > "Kleuskes & Moos" <kleu...@xs4all.nl> writes: > > > On May 4, 5:26 pm, Keith Thompson <ks...@mib.org> wrote: > [...] > >> Well, sort of. The argument of the is*() function is an int, > >> but its value is required to be representable as an unsigned char > >> or to be equal to EOF. The standard *could* have specified some > >> kind of error handling for isalpha(UCHAR_MAX + 1), but instead it > >> just says the behavior is undefined. Similarly, the behavior of > >> feof(FILE*(NULL)) is undefined. > > > Aye, it could have introduced a check, and it might have ordained > > array-bounds-checking, too, but the fact of the matter is it doesn't. > > and it seems aginst the spirit of C, too. Besides, returning false for > > isalpha(65535) is a very reasonable implementation of that particular > > bit of undefined behavior and I suspect most compilers will do. > > In my experience, at least some implementations define macros for > the is*() functions, macros that work by indexing into arrays. > isalpha(65535) will go well outside the bounds of the array, > with unpredictable results. True. That would be another acceptable implementation of undefined behavior, not the most convenient one, but still. > (At least one implementation I've > seen defensively allows for small negative arguments, so (signed) > char arguments work as they should, even though the standard doesn't > require them to. But you shouldn't depend on that.) Depending on undefined behavior is a no-no of epic proportions anyway, however conveniently the actual implementation deals with it. But that's kicking in an open door... Tjuus, Kleuske.
[toc] | [prev] | [next] | [standalone]
| From | James Dow Allen <jdallen2000@yahoo.com> |
|---|---|
| Date | 2011-05-03 03:45 -0700 |
| Message-ID | <296771a0-5798-4bcc-859a-7cd4d48a7c06@z7g2000prh.googlegroups.com> |
| In reply to | #3162 |
As James Kuyper says, best is to have the return value
implicit in the function name:
is_kosher(this.soup) && do_serve(&this);
or
dad = find_father();
if (dad == NULL) {
/* process orphan */
}
Letting zero represent incorrect/error is often good enough:
many simple programs will handle all error returns from a
simple function the same, so a single error "reason" is enough.
James
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-05-03 20:50 +0000 |
| Message-ID | <slrnis0ql4.gtj.grahn+nntp@frailea.sa.invalid> |
| In reply to | #3169 |
On Tue, 2011-05-03, James Dow Allen wrote:
> As James Kuyper says, best is to have the return value
> implicit in the function name:
> is_kosher(this.soup) && do_serve(&this);
> or
> dad = find_father();
> if (dad == NULL) {
> /* process orphan */
> }
>
> Letting zero represent incorrect/error is often good enough:
> many simple programs will handle all error returns from a
> simple function the same, so a single error "reason" is enough.
Yes. In my experience, lots of people want to be as generic as possible
and let pretty much *everything* have 0 for success and non-zero for
failure. This makes the calling code much harder to read.
It's worth /a lot/ to have calling code which reads naturally, like J.D.A.'s
examples above. Not like strcmp() or many POSIX functions.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-05-03 07:50 -0400 |
| Message-ID | <4DBFEBF4.5147@mindspring.com> |
| In reply to | #3162 |
pozz wrote: > > A very simple question. What do you use as the return value of a > function for error/ok results? > I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0 > for errors. When there may be several various error return codes, then use 0 for success. When there are *not* several various error return codes, such as in the isspace function and the the other <ctype.h> functions, then use 0 for failure. -- pete
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-05-03 12:04 -0700 |
| Message-ID | <ln62prvc50.fsf@nuthaus.mib.org> |
| In reply to | #3171 |
pete <pfiland@mindspring.com> writes:
> pozz wrote:
>> A very simple question. What do you use as the return value of a
>> function for error/ok results?
>> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
>> for errors.
>
> When there may be several various error return codes,
> then use 0 for success.
>
> When there are *not* several various error return codes,
> such as in the isspace function
> and the the other <ctype.h> functions,
> then use 0 for failure.
As I said in another followup, the is*() functions don't return
0 for *failure*. A return value of 0 means that the function
successfully answered the question -- and the answer was no.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Martin Ambuhl <mambuhl@earthlink.net> |
|---|---|
| Date | 2011-05-03 07:59 -0400 |
| Message-ID | <7PydnbOre7mNcyLQnZ2dnUVZ_tSdnZ2d@earthlink.com> |
| In reply to | #3162 |
On 5/3/2011 4:31 AM, pozz wrote: > Another strategy is to define custom error code: > > #define ERROR_OK 0 > #define ERROR_UNDEFINED 1 > #define ERROR_WRONGVALUE 2 But not with those names. These names are reserved for the implementation.
[toc] | [prev] | [next] | [standalone]
| From | Mark Storkamp <mstorkamp@yahoo.com> |
|---|---|
| Date | 2011-05-03 08:46 -0500 |
| Message-ID | <mstorkamp-AB5B3A.08455403052011@62-183-169-81.bb.dnainternet.fi> |
| In reply to | #3162 |
In article <error-codes-20110503151314@ram.dialup.fu-berlin.de>,
ram@zedat.fu-berlin.de (Stefan Ram) wrote:
> pozz <pozzugno@gmail.com> writes:
> >I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> >for errors.
>
> 0 means »no error«, since there is only one way to
> succeed, but many ways to fail.
>
> >if (!myfuction()) printf("OK\n");
>
> Yes, the »!« looks ugly there, but often one wants to handle
> the error in some way:
To steal a page from BCPL you can always do something like this:
#define unless(c) if(!(c))
Then you have
unless (myfunction()) printf("OK\n");
>
> if( int const code = alpha() )error( code ); else printf ...
>
> (I know that one cannot define variables in the
> if expression, but it would be nice.)
[toc] | [prev] | [next] | [standalone]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2011-05-03 10:13 -0500 |
| Message-ID | <ipp639$des$1@dont-email.me> |
| In reply to | #3162 |
On 03-May-11 03:31, pozz wrote:
> A very simple question. What do you use as the return value of a
> function for error/ok results?
> I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> for errors.
General rules:
1. If one success state and many error states, let 0 indicate success.
2. If one error state and many success states, let 0 indicate error.
3. If many success states and many error states, let negative indicate
error and non-negative indicate success.
> If !=0 is ok, I can write:
>
> if (myfunction()) printf("OK\n");
>
> but I have only one error code (0), while, in some cases, it could be
> useful to have more informations about the type of error.
This is usually the case.
> If !=0 is error I can have several error codes, but I have to write
>
> if (!myfuction()) printf("OK\n");
>
> that apparently seems myfunction has not terminated with success.
You could consider rewriting that line as:
if (myfuction()==0) printf("OK\n");
That form has the same meaning to the compiler, but some folks feel it
conveys a different/better meaning to humans. This frequently comes up
in debates about strcmp() et al, for example.
S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
[toc] | [prev] | [next] | [standalone]
| From | William Ahern <william@wilbur.25thandClement.com> |
|---|---|
| Date | 2011-05-03 13:08 -0700 |
| Message-ID | <ru3698-ldj.ln1@wilbur.25thandClement.com> |
| In reply to | #3181 |
Stephen Sprunk <stephen@sprunk.org> wrote:
> On 03-May-11 03:31, pozz wrote:
> > A very simple question. What do you use as the return value of a
> > function for error/ok results?
> > I can't decide between 0 for error and !=0 for ok, or 0 for ok and !=0
> > for errors.
> General rules:
> 1. If one success state and many error states, let 0 indicate success.
> 2. If one error state and many success states, let 0 indicate error.
> 3. If many success states and many error states, let negative indicate
> error and non-negative indicate success.
This is the approach taken by snprintf(), and it's very annoying. On success
you end up with a value that really should be kept in a size_t, for
comparing with other similar values. Which means you inevitably end up
having to convert (or worry about missed implicit conversions) the value in
the common case. Then, to make matters worse, almost half the value space is
wasted for a simple -1. And to add insult to injury, although there can be
multiple error states, you still have to query a separate object. (So I
guess it sort of falls between #2 and #3.)
I would discard #3. If there are many error states, overload a single value
in the success space (an unlikely value, like 0, or more importantly a value
which if misused is unlikely to cause havoc, also typically 0), and take a
separate parameter analogous to errno. Otherwise, just return an errno-like
object.
I religiously follow #1 and #2. If #1, I return an (int). If #2 I take a
pointer to an (int). Positive values for the (int) object are reserved for
saving errno or reusing standard error macros. The standard says that errno
values most be positive, and if POSIX doesn't also guarantee this for
extensions it appears to be the universal behavior.
Negative values I reserve for application use, to be apportioned to each
library. To avoid clashes, present and future, I store in the upper bits a
likely unique identifer. For example, the error range for my DNS library
will start at -(('D' << 24) | ('N' << 16) | ('S' << 8)). (I realize (int) is
only guaranteed to be 16-bits, but the principle still applies, although
perhaps not as simple.)
I've toyed with the idea of overloading strerror(), but in general as long
as library dependencies are hierarchical and fairly shallow (as they almost
always are in practice), then simply passing an error value to the
_strerror() method of a library is sufficient, and each library can forward
negative errors as necessary, passing positive errors to strerror().
I use this method everywhere, often wrapping standard routines like malloc
and snprintf:
void *make(size_t size, int *error);
size_t fmtstr(void *dst, size_t lim, int *error, const char *fmt, ...);
It has worked extremely satisfactorily for a couple of years now. Since I
settled on this solution I haven't looked back. It has regularized by my
error handling habits, where how a particular routine returns an error is
not nearly as important as consistency and convenience across all the
routines.
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-05-03 13:23 -0400 |
| Message-ID | <L6OdnYkzV8mMp13QnZ2dnUVZ_tidnZ2d@bestweb.net> |
| In reply to | #3162 |
On 5/3/2011 4:31 AM, pozz wrote: [...] > #define ERROR_OK 0 > #define ERROR_UNDEFINED 1 > #define ERROR_WRONGVALUE 2 [...] Nit: Those are, technically, all reserved for implementation-defined error codes. (7.26.2 reserves "macros that begin with E and a digit or E and an uppercase letter".) -- Kenneth Brody
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web