By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,851 Members | 1,131 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,851 IT Pros & Developers. It's quick & easy.

Error handling in C

P: n/a
Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Nov 19 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
arnuld wrote:
Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(
If there's a good document on the topic, I haven't seen it.
But I'll offer a few thoughts; take 'em or leave 'em.

There are two aspects to error handling: Detection of the
error condition and response to it. The first is dictated by
the API you're using: A function is documented to return NULL
or to set a global variable to 0xBaddBadd or whatever, and it's
up to you as the function's caller to make the indicated test.
If you're writing your own functions and want to report errors
from them, you can choose whatever means you like; consider the
other existing functions you use and imitate the style of those
you find easiest to get along with.

Once the error is detected, the response is a much thornier
problem. It has more to do with the structure of your program
and with the way the program is used than with the error itself.
Often, you want to get back to a "neutral state" where a user
can try the operation again, or try a different operation. But
for some programs there may be no "user:" a program that runs
unattended can't very well ask Higher Authority what to do if
something goes wrong. This is an area of great difficulty.

Some languages provide frameworks that favor a particular
style of error handling, things like "exceptions" in C++ or
Java, for example. C doesn't offer much of this sort of thing,
which is sometimes a curse and sometimes a blessing.
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
If you can write specifications this clearly and precisely,
you'll have a brilliant and successful career -- in management.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 19 '08 #2

P: n/a
On 19 Nov, 13:11, arnuld <sunr...@invalid.addresswrote:
Can anyone point me to some online/offline document on error handling in C?
I've never seen a good one. Doesn't mean there isn't one, just I've
never seen it.
I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(
yeah, error handling in C can be a pain. Especially if you've used
something with exceptions.

You might end up with something like this:-

<code>
int activesock (const char *host, int port, const char *protocol)
{
struct hostent *phe;
struct servent *pse;
struct protoent *ppe;
struct sockaddr_in sin;
int s, type;

memset (&sin, 0, sizeof sin);

sin.sin_family =AF_INET;
sin.sin_port = htons (port);

/* map host name to ip addr allowing for dotted decimal */
if ((phe = gethostbyname (host)))
memcpy (&sin.sin_addr, phe->h_addr, phe->h_length);
else
if ((sin.sin_addr.s_addr = inet_addr (host)) == INADDR_NONE)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
host entry\n", host);

/* map protocol name to protocol number */
if ((ppe = getprotobyname (protocol)) == 0)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
protocol entry\n", protocol);

/* use protoicol to choose socket type */
if (strcmp (protocol, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;

/* allocate a socket */
/* s = socket (PF_INET, type, ppe->p_proto); */
s = socket (PF_INET, type, DEFAULT_PROTOCOL);
if (s < 0)
raise_report (LEVEL_FATAL, "activesock", "can't create socket:
%s\n", strerror (errno));

/* connect to the socket */
if (connect (s, (struct sockaddr *)&sin, sizeof sin) < 0)
raise_report (LEVEL_FATAL, "activesock", "can't connect to %s.
%d: %s\n", host, port, strerror (errno));

return s;
}
</code>
basically you have to check the return value of every function.
But then that's good for you. Much as eating your vegetables and
drinking 2 pts of water is good for you.

In the above raise_report() writes to a log file and possibly
terminates the program.

A language with exceptions can look much nicer

<code>
DEFAULT_PROTOCOL = 0

sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM,
DEFAULT_PROTOCOL)

if len (sys.argv) < 2 :
host = "localhost"
else:
host = sys.argv [1]

sock.connect ((host, 8702))
</code>

But, of course, exceptions have their own pitfalls.

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
I don't think you can do this in C89. C99 has something like
__function__()
(I can't rememeber the exact spelling). My report routine above
takes a parameter for the function name. To be honest __FILE__ and
__LINE__ are usually good enough for me. Ok you don't want the user
to
see file and line, but then you don't want him to see function either.

One trick is to have your functions return an error value.

Rv do_big_thing()
{
do_sub_thing1();
do_sub_thing_2();
return OK;
}

this can be nested

Rv do_big_thing()
{
if ((rv = do_sub_thing1()) != OK)
{
log_error();
return rv;
}

if ((rv = do_sub_thing_2()) != OK)
{
log_error();
return rv;
}

return OK;
}

with suitable macro trickery this reduces to

Rv do_big_thing()
{
CHECK_CALL (do_sub_thing1());
CHECK_CALL (do_sub_thing_2());
return OK;
}

of course I now have a nasty macro, a global variable and a function
with multiple exits.

The price of greenspunning

--
Nick Keighley

why isn't there an obfuscated C++ contest?
Nov 19 '08 #3

P: n/a
arnuld wrote:
....
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
In C99 you can use the pre-defined identifier __func__. When used, it
behaves exactly as if the following declaration had been inserted
immediately after the '{' at the start of the enclosing function:

static const char __func__[] = "function-name";

This feature was not available in C89, and I know of no way to do what
you're asking for without making use of __func__.

Nov 19 '08 #4

P: n/a
Nick Keighley wrote:
On 19 Nov, 13:11, arnuld <sunr...@invalid.addresswrote:
<snip>
>Also some time ago some one told me that when I get an error then I
can create a generic function which, when called within some
function will print the name of that function automatically or
something like that I forgot. It had lots of #define(s) . Can
someone write that for me ?

I don't think you can do this in C89. C99 has something like
__function__()
(I can't rememeber the exact spelling).
__func__ and it's a string, not a macro (and not a function like macro
either)

I once had a hard time searching for in in the standard. Searching for
_func_ works and finds
_ _func_ _ (with a small space bewteen the _)

bye, Jojo
Nov 19 '08 #5

P: n/a
arnuld <su*****@invalid.addresswrites:
Can anyone point me to some online/offline document on error handling in C
?
I am not aware of one, sorry.
I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(
A common error I used to see in people starting out is to write the
program as if all is well and then, later, try to put the error
handling in. This does not work in C. You have to design the program
to handle all the failures you care about from the start. If you
haven't done this then, no matter how painful it may seem, you will
probably be better off starting over (you will be able to re-use bits
you've written so it is only the design you must re-do).

Most things work only one way but can fail in numerous ways. This
means there is often more code to handle errors than anything else.
If your algorithms are reasonably complex there may be a fair balance,
but a server that does something quite simple will be mostly error
handling code!
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
Do you mean something that simply reports errors? If so a starting
point might be (uses C99):

#define REPORT(...) do { \
fprintf(stderr, "In %s(): ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)

though I'd be inclined to turn this into a function with a simpler macro
as a wrapper.

--
Ben.
Nov 19 '08 #6

P: n/a
In article <gg**********@news.motzarella.org>,
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
C doesn't offer much of this sort of thing,
which is sometimes a curse and sometimes a blessing.
That one sentence, presented without context, makes an excellent
summary of pretty much everything that people love and hate about C.
dave

--
Dave Vandervies dj3vande at eskimo dot com
No-one has a fully functional brain; brains have mutable (and
mutated) state.
--Chris Dollin in comp.lang.c
Nov 19 '08 #7

P: n/a
arnuld wrote:
Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
If you have a C99 implementation, the function name is the predefined
identifier __func__ which follows block scoping rules. Your code needs
nothing long or involved:

/* C99 example */
#include <stdio.h>

void whoami(void)
{
fprintf(stderr, "Function %s does almost nothing\n". __func__);
}

Many pre-C99 implementations provide a similar mechanism, but this will
often be a macro (__func__ behaves as if it were a block-scope pointer
to static const char[].). For example, if you use GCC 3.4 or later, its
special name __FUNCTION__ behaves like __func__, but for GCC 3.3 or
earlier __FUNCTION__ behaved like a string constant, just as __FILE__,
__DATE__, and __TIME__ were and still are string constants. In
implementations for which the functionality of the C99 __func__ is
approximated with a macro expanding to a string constant, the above
approach still works:

/* example of one non-standard C89 extension, where the predefined
macro __FUNCTION__ expands to a string constant */
#include <stdio.h>

void whoami(void)
{
fprintf(stderr, "Function %s does almost nothing\n".
__FUNCTION__);
}

There are other ways to use macros that expand to string constants which
are not available when using __func__, but for just that reason they
should be avoided. But here is an example that should continue to work:

#include <stdio.h>
#if !defined(__FUNCTION__)
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define __FUNCTION__ __func__
#else
#define __FUNCTION__ "<unknown>"
#endif
#endif
void whoami(void)
{
fprintf(stderr, "At line %d in " __FILE__ "\n"
"Translated at " __TIME__ "on " __DATE__ "\n"
"In function %s\n."
__LINE__, __FUNCTION__);
}
Nov 19 '08 #8

P: n/a
On Nov 19, 8:33*am, Eric Sosman <es*****@ieee-dot-org.invalidwrote:
* * *Some languages provide frameworks that favor a particular
style of error handling, things like "exceptions" in C++ or
Java, for example. *C doesn't offer much of this sort of thing,
which is sometimes a curse and sometimes a blessing.
C doesn't provide those, but there are frameworks, such as:
http://home.rochester.rr.com/bigbyofrocny/GEF/

Sebastian

Nov 19 '08 #9

P: n/a
arnuld wrote:
>
Can anyone point me to some online/offline document on error
handling in C ?

I am doing some Socket Programming in C and feeling a lots of
difficult in error handling :(
Sockets are not part of standard C, and are thus off-topic in
c.l.c. You can reference the standard in the following:

Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://c-faq.com/ (C-faq)
<http://benpfaff.org/writings/clc/off-topic.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf(C99)
<http://cbfalconer.home.att.net/download/n869_txt.bz2 (pre-C99)
<http://www.dinkumware.com/c99.aspx (C-library}
<http://gcc.gnu.org/onlinedocs/ (GNU docs)
<http://clc-wiki.net/wiki/C_community:comp.lang.c:Introduction>
>
Also some time ago some one told me that when I get an error then
I can create a generic function which, when called within some
function will print the name of that function automatically or
something like that I forgot. It had lots of #define(s) . Can
someone write that for me ?
No, but here is all you need, from the standard (needs C99):

6.4.2.2 Predefined identifiers

Semantics

[#1] The identifier __func__ shall be implicitly declared by
the translator as if, immediately following the opening
brace of each function definition, the declaration

static const char __func__[] = "function-name";

appeared, where function-name is the name of the lexically-
enclosing function.53)

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 20 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.