473,322 Members | 1,421 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

What's The Best Practice Defining Error Codes in C

Hi,

I would like to have someone comments on what's the best practice
defining error codes in C.
Here's what I think:
solution A:
using enum
pros: type safe. better for debug (some debugger will show the name
not only the value)
cons: enum can not be forward declared which makes all error codes
couples together with the error code type ( enum )

Solution B:
using #define
pros: decouple, error codes could be defined in different .h file
cons: macro is bad. no type safe

Solution C:

typedef struct Error
{
int value;
} Error;

static Error const ERROR_OUT_OF_SPACE = { 123 };

pros: type safe. decouple, the error code type is no longer bound with
all the error definition
cons: I don't know any one doing it this way so I'm not sure if it has
some drawbacks or is it bad for (runtime/space) performance.
If using pure C, user could not compare the error value directly but
have to compare the inner "value" member which is not convenience.

Thanks for your help :)

Qiang
Nov 16 '08 #1
5 13423
׿ǿ Zhuo wrote:
Hi,

I would like to have someone comments on what's the best practice
defining error codes in C.
Here's what I think:
solution A:
using enum
pros: type safe. better for debug (some debugger will show the name
not only the value)
cons: enum can not be forward declared which makes all error codes
couples together with the error code type ( enum )
By "can not be forward declared," I guess you mean that
you cannot just invent a new error code at some random place
in the program; is that right? If so, I'd say this should be
considered a "pro" and not a "con."
Solution B:
using #define
pros: decouple, error codes could be defined in different .h file
cons: macro is bad. no type safe
"Macro is bad" is bad.
"`Macro is bad' is bad" is bad.
"`«Macro is bad» is bad' is bad" is bad.
...
Solution C:

typedef struct Error
{
int value;
} Error;

static Error const ERROR_OUT_OF_SPACE = { 123 };
Careful! If you include the <errno.hheader -- or if any
code that refers to ERROR_OUT_OF_SPACE includes <errno.h--
Then all identifiers beginning with an E and another upper-case
letter or beginning with E and a digit are reserved.
pros: type safe. decouple, the error code type is no longer bound with
all the error definition
If by "decouple" you mean that it is now possible to invent
new error codes at any random place in the program, I'd say this
should be a "con" rather than a "pro." For one thing, there's
no convenient way to be sure error codes aren't duplicated: what
if somebody defines OUT_OF_CHEESE_ERROR with the value 123?
cons: I don't know any one doing it this way so I'm not sure if it has
some drawbacks or is it bad for (runtime/space) performance.
If using pure C, user could not compare the error value directly but
have to compare the inner "value" member which is not convenience.
Right: Opacity is lost. Also, so is contant-ness, in the
sense that the error objects are not compile-time constants.
You can't use them as `case' labels, for example.

Solutions (A) and (B) are the most common in code I've seen
over the years. I've never seen (C), not in such a bare-bones
form at any rate.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 16 '08 #2
On Sun, 16 Nov 2008 04:48:38 -0800 (PST),
=?GB2312?B?17/HvyBaaHVvLCBRaWFuZw==?= <zh********@gmail.com>
wrote:
>Hi,

I would like to have someone comments on what's the best practice
defining error codes in C.
Here's what I think:
solution A:
using enum
pros: type safe. better for debug (some debugger will show the name
not only the value)
cons: enum can not be forward declared which makes all error codes
couples together with the error code type ( enum )

Solution B:
using #define
pros: decouple, error codes could be defined in different .h file
cons: macro is bad. no type safe

Solution C:

typedef struct Error
{
int value;
} Error;

static Error const ERROR_OUT_OF_SPACE = { 123 };

pros: type safe. decouple, the error code type is no longer bound with
all the error definition
cons: I don't know any one doing it this way so I'm not sure if it has
some drawbacks or is it bad for (runtime/space) performance.
If using pure C, user could not compare the error value directly but
have to compare the inner "value" member which is not convenience.
All choices suffer from the same fundamental flaw; they use error
codes. The advantages of error codes are that they compact and
that they are testable, i.e, if a routine returns an error code
you can take appropriate action based on the error code. These
are advantages in the small.

So, if all you are concerned about is one module, you can use
error code definitions in the modules include file, and it
doesn't much matter whether you use enums or defines - the
decision is a religious one.

Using error codes in a larger scope is not a happy policy. If
you have several people working on a program or collection of
programs you end up with a lot of error codes, and version
control problems. The issue is that the definition of error
codes becomes a version control sensitive bottleneck. There are
various techniques for handling the problem; still you have to
know in advance that there is an issue. Otherwise you eventually
end up with a mess that has to be cleaned up - or lived with.

There is another issue with error codes when programming in the
large; they aren't a solution, they are a tool. Does your big
application have a coherent error management policy? Then error
codes are a detail; if not, then the tail is wagging the dog.

Richard Harter, cr*@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
Nov 16 '08 #3

"Richard Harter" <cr*@tiac.netwrote in message
There is another issue with error codes when programming in the
large; they aren't a solution, they are a tool. Does your big
application have a coherent error management policy? Then error
codes are a detail; if not, then the tail is wagging the dog.
The real answer is that there is no answer.

What's an error, anyway. Do we mean the machine running out of memory, which
is the only thing that can happen to pure functions, as long as they are
correctly written and called, do we mean internal programmer errors, do we
mean missing resources or bad user input? Does it make sense to handle these
together or separately?

Eg in my program BASICdraw the user will frequently enter a Basic program
with syntax errors in it. However this is to be expected. It can't be
handled in the same way as the machine running out of disk space to store
images.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Nov 16 '08 #4
On 11月16日, 下午9时47分, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
׿ǿ Zhuo wrote:
Hi,
I would like to have someone comments on what's the best practice
defining error codes in C.
Here's what I think:
solution A:
using enum
pros: type safe. better for debug (some debugger will show the name
not only the value)
cons: enum can not be forward declared which makes all error codes
couples together with the error code type ( enum )

* * *By "can not be forward declared," I guess you mean that
you cannot just invent a new error code at some random place
in the program; is that right? *If so, I'd say this should be
considered a "pro" and not a "con."
Yes and No. As a module We'd like to split the error code to two
category, those for the client and those inside. We don't want to
define all the error code in one place which introduce unnecessary
couple. But for one category, it's better that they are defined in one
place.

Solution B:
using #define
pros: decouple, error codes could be defined in different .h file
cons: macro is bad. no type safe

* * *"Macro is bad" is bad.
* * *"`Macro is bad' is bad" is bad.
* * *"`«Macro is bad» is bad' is bad" is bad.
* * *...
So I guess you dislike macro either :)
Solution C:
typedef struct Error
{
int value;
} Error;
static Error const ERROR_OUT_OF_SPACE = { 123 };

* * *Careful! *If you include the <errno.hheader --or if any
code that refers to ERROR_OUT_OF_SPACE includes <errno.h--
Then all identifiers beginning with an E and another upper-case
letter or beginning with E and a digit are reserved.
Thanks for the reminder. Actually all identifiers are prefixed with
module name.(how long will namespace be introduced into C)
pros: type safe. decouple, the error code type is no longer bound with
all the error definition

* * *If by "decouple" you mean that it is now possible to invent
new error codes at any random place in the program, I'd say this
should be a "con" rather than a "pro." *For one thing, there's
no convenient way to be sure error codes aren't duplicated: what
if somebody defines OUT_OF_CHEESE_ERROR with the value 123?
Yes, By decouple I mean the possibility to define new error code
somewhere else. I know it requires discipline to do so. Like I said
we'd like to separate private error code from public interface.
cons: I don't know any one doing it this way so I'm not sure if it has
some drawbacks or is it bad for (runtime/space) performance.
If using pure C, user could not compare the error value directly but
have to compare the inner "value" member which is not convenience.

* * *Right: Opacity is lost. *Also, so is contant-ness, in the
sense that the error objects are not compile-time constants.
You can't use them as `case' labels, for example.
Good point. I guess I have to drop the C) choice

>
* * *Solutions (A) and (B) are the most common in code I've seen
over the years. *I've never seen (C), not in such a bare-bones
form at any rate.
I will stick with solution A) for now.

However, another silly question:

How about:

typedef struct ErrorTag* Error;
static Error const = 123;

I'm living in C++ world, so I want to try my best to make the API type
safe. Is there any way except enum could give a type safe error code
solution ?

Thanks for your time :)
--
Eric Sosman
esos...@ieee-dot-org.invalid
Nov 17 '08 #5
Zhuo wrote:
On 11月16日, 下午9时47分, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
>׿ǿ Zhuo wrote:
>>[...]
using #define
pros: decouple, error codes could be defined in different .h file
cons: macro is bad. no type safe
"Macro is bad" is bad.
"`Macro is bad' is bad" is bad.
"`«Macro is bad» is bad' is bad" is bad.
...
So I guess you dislike macro either :)
No, I mean that unqualified and unsupported out-of-context
statements of the form "X is bad" are bad.
>>Solution C:
typedef struct Error
{
int value;
} Error;
static Error const ERROR_OUT_OF_SPACE = { 123 };
Careful! If you include the <errno.hheader -- or if any
code that refers to ERROR_OUT_OF_SPACE includes <errno.h--
Then all identifiers beginning with an E and another upper-case
letter or beginning with E and a digit are reserved.
Thanks for the reminder. Actually all identifiers are prefixed with
module name.(how long will namespace be introduced into C)
Make sure, then, that you don't name a model EVAPORATE or
EXISTENTIAL or ENNUI or ...

As for the question about name spaces -- well, it's a lot easier
to predict the future after it's happened, right? But my guess is
that name spaces (in the form you probably want them) will never
come to C.
However, another silly question:

How about:

typedef struct ErrorTag* Error;
static Error const = 123;
This is fine -- if you don't mind the diagnostic the compiler
is required to emit and if the compiler accepts the code in spite
of the constraint violation.
I'm living in C++ world, so I want to try my best to make the API type
safe. Is there any way except enum could give a type safe error code
solution ?
I'm not sure why you're so insistent on type safety for error
codes. No doubt type safety beats "type peril" everywhere, but how
important is it here? What kinds of misuse do you fear might befall
your error codes, anyhow?

In any case, C's enum will not provide much type safety. The
named constants are all of type `int', just plain `int', and there's
nothing in the language that prevents them from being used just as
`1' or `42' can be used.

--
Er*********@sun.com
Nov 17 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Zhang Weiwu | last post by:
Hello. I am working with a php software project, in it (www.egroupware.org) Chinese simplified locate is "zh" while Traditional Chinese "tw". I wish to send correct language attribute in http...
9
by: Mark Twombley | last post by:
Hi, I'm just getting back into C++ and had a question about the best practice for assigning error numbers. I have been working in VB for sometime now and there you would start assigning error...
11
by: modemer | last post by:
If I define the following codes: void f(const MyClass & in) {cout << "f(const)\n";} void f(MyClass in) {cout<<"f()\n";} MyClass myclass; f(myclass); Compiler complain that it can't find...
2
by: Dave | last post by:
Does anyone know much about this tool? Also, if anyone can point me to a TSQL coding standard, please let me know. -- Dave
4
by: Nobody | last post by:
Lets say I have a class that is only available if a specific DLL (a.dll) is present. I can't link to that DLL through lib files or my app will fail on any machine that doesn't have a.dll. So I...
4
by: Robert Zurer | last post by:
Hello All, Is it considered a best practice to always write a parameterless constructor for any object - just in case? I'm not sure. I want my object to have all it absolutely requires to...
10
by: Mike Logan | last post by:
I am using the "contract first" design methodology. Contract First is design the WSDL first then design the server and client. However I must design my XSD/XML Schema before anything. I am...
669
by: Xah Lee | last post by:
in March, i posted a essay “What is Expressiveness in a Computer Language”, archived at: http://xahlee.org/perl-python/what_is_expresiveness.html I was informed then that there is a academic...
5
by: Jens | last post by:
Hello, I have been looking for some C-code which listens on a user-defined port for incoming data traffic. When data is received, the data is written to a file. I found some C-code (server)...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, youll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.