Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Exceptions in C

Name: Anonymous 2008-06-14 8:02

i made an exception handling header for C and thought /prog/ could find a use for it, anyway, enjoy:
(simple usage below)

exception.h
/**
 * exception handling for ANSI C
 * \note NOT thread-safe \br
 * values of automatic variables are unspecified (look to longjmp(3) man page)
 */
#ifndef __EXCEPTION_H
#define __EXCEPTION_H

/// programmer can declare this to achive deeper recursion
#ifndef __EXMAXNEST
#       define __EXMAXNEST 16
#endif
/// simple stack for environment buffers used by setjmp()
jmp_buf  __exbuf[__EXMAXNEST];
/// simple stack for exit values of longjmp()
int      __exvalue[__EXMAXNEST];
/**
 * simple stack to check if current exception has been handled
 * (needed for upward propagation)
 */
char     __exhandled[__EXMAXNEST];
/// simple stack pointer
int      __exnest = 0;

/// try block
#define try      {                                                           \
                    if(__exnest >=  __EXMAXNEST) {                           \
                        fprintf(stderr, "%s:%i: Too deep try (...) catch "   \
                                "recursion. Aborting... \n", __FILE__,       \
                                __LINE__);                                   \
                        abort();                                             \
                    }                                                        \
                    __exhandled[__exnest] = 0;                               \
                    if ((__exvalue[__exnest] =                               \
                         setjmp(__exbuf[__exnest++])) == 0) {
/// catch block
#define catch(x)    } else if (__exvalue[__exnest-1] == (x) ) {              \
                        __exhandled[__exnest-1] = 1;                         \
                        --__exnest;
/**
 * finally block
 * \note must be always included, even if no code goes into finally block
 */
#define finally     } else {                                                 \
                        __exhandled[__exnest-1] = 0;                         \
                        --__exnest;                                          \
                    }
/// closing part for try block
#define end_try     if( __exhandled[__exnest] == 0)                          \
                        if (__exnest != 0) {                                 \
                            longjmp(__exbuf[__exnest-1],                     \
                                    __exvalue[__exnest]);                    \
                        } else {                                             \
                            fprintf(stderr, "%s:%i: Unhandled "              \
                                    "exception %i. Aborting...\n",           \
                                    __FILE__,  __LINE__,                     \
                                    __exvalue[__exnest]);                    \
                            abort();                                         \
                        }                                                    \
                }
/// throws exception given as a parameter
#define throw(x)    longjmp(__exbuf[__exnest-1], (x))
/**
 * makes current exception unhandled (it will be propagated upwards), useful
 * to just print debug mesages from local variables and continue
 * unvinding the stack
 * \note can be safely used only in catch() block
 */
#define unhandled   __exhandled[__exnest] = 0
/**
 * does basically the same thing as unhandled but can
 * change exception type, better that throw in catch() because it doesn't make
 * the finally block unexecuted
 * \note can be safely used only in catch() block
 */
#define rethrow(x)  __exhandled[__exnest] = 0;                               \
                    __exvalue[__exnest] = (x)

#else

extern jmp_buf  __exbuf[__EXMAXNEST];
extern int      __exvalue[__EXMAXNEST];
extern char     __exhandled[__EXMAXNEST];
extern int      __exnest;

#endif


usage:
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include "exception.h"

int func(int a)
{
        throw(1);
}

int main(int argc, char** argv)
{
        try
                func(2);
        catch(2)
                printf("exception catched\n");
        catch(1)
                printf("weird exception, make it unhandled\n");
                unhandled;
        finally
                printf("always executed\n");
        end_try

        exit(0);
}

Name: Anonymous 2008-06-14 9:06

Ah, but have you forgotten about our NO EXCEPTIONS policy?

Is it reentrant? Is it threadsafe? (no need to answer, really)

I'll stick to my 100% compatible call/cc implementation in C, thanks.

Name: Anonymous 2008-06-14 9:06

data Char       = 'a' | 'b' | 'c' | ...         -- This is not valid
                | 'A' | 'B' | 'C' | ...         -- Haskell code!
                | '1' | '2' | '3' | ...
                ...

Name: Anonymous 2008-06-14 9:18

>>3
But this is:

import System

shitIceCream level
   | level < 0 = error "shitIceCream: negative level"
   | otherwise =
        reverse $ (\(a, b) -> a ++ "_" ++ tail b) $ break (==' ') $ reverse $ unlines
                $ (\(a: b: cs) -> a: tail b: cs)
                $ zipWith (++) (reverse $ take (level + 3) $ iterate (' ':) "")
                $ zipWith ($) (cycle [((++".") . (' ':)), ('.':)])
                $ ("":) $ (" ,":) $ map (++"/ )")
                        $ ("":)   $ map ('(':) $ iterate (++"__") "_"

main = putStr . shitIceCream . read . unwords =<< getArgs

Name: Anonymous 2008-06-14 9:19

i'm a n00b programmer that knows the c basics and has used it for smaller projects but i learned c without books and without having english as a native language so a lot of terms written on say wikipedia pages about exception handling are foreign to me

could op please tell me about an example where an exception handler is used in a real life application?

Name: Anonymous 2008-06-14 9:25

>>4
It's also unreadable.

Name: Anonymous 2008-06-14 9:37

>>6
I can read it.

Name: Anonymous 2008-06-14 9:49

http://www.on-time.com/ddj0011.htm

oh i get it now, it's just error handling, meh, too often i get impressed by some fancy terms and it turns out to be something i've known for ages

but i have never known how to do it in c so thanks for the code OP

Name: Anonymous 2008-06-14 9:56

>>2
i'm now working on pthread aware implementation of exceptions
looks good so far, it will have to use thread specific data for this and as i have a bit more to put to it the result will, no doubt, be intresting as i want to have universal code usable in other projects

yes call/cc is reentrant, i didn't know it's threadsafe though... care to point me to an example implementation?

>>5
real life application? it's hard not to use exceptions IRL programming and the applications are numerus but complex and hard to summarize in a simple BBS post (network communication and database interaction are places where it's most useful)

but consider this example:
there's a function that returns integers (both negative and positive) and accepts two arguments
let's say that one of those two arguments have to be smaller than some value and second one bigger than some value

we can't use a special return (either negative or positive) as the functions returns them in normal operation, and we can't use 0, as we have two different situations

with exceptions we can throw exception nr 1 from inside of this function if the first value is too big and a exception nr 2 if the second is too small

in exception handling we can inform user that either this one or that one argument to function is too big

and then in finally block free memory, close db connections etc.

you can, of course, check it before calling the function, but if you take into cosideration that you call the function from multiple places and that the code is written by few people, then it's ineffective and error prone

Name: Anonymous 2008-06-14 10:05

>>5,8
Genuine questions? Humble attitude? Polite language?

May I ask what the fuck you think you're doing in my /prog/, sir?

Name: Anonymous 2008-06-14 10:15

>>10
You have just witnessed passive-aggressive trolling.

Also:
>>1,5,8,9
Same person and we have been trolled constantly.

Name: Anonymous 2008-06-14 10:16

>>5
Traditionally, error notification and handling is done by one of two methods.

One is to use a special return code in your function that indicates an error occurred, and then use an auxiliary function or value to determine the type of error. For example, C's errno or Win32's GetLastError().

The other is to jump to another specified location in your program whenever an error condition is detected. For example, BASIC's ON ERROR GOTO or DOS batch language's IF ERRORLEVEL ... GOTO.

Exception handling differs from these in that it tries to provide a neater structure for handling errors. You no longer have to use an arbitrary return code to indicate error, and you don't have to jump somewhere else in your program or calling function - the error handling code is always in a certain defined block.

For example, here's how you might open a file with exception handling (in pseudocode):

  try:
    f = open(filename)
  catch FileNotFound:
    print "cannot find "+filename
  catch AccessDenied:
    print "no permission to open "+filename
  except:
    print "unknown error number "+error+" opening "+filename


Note the neat way in which error handling code is separated out into different blocks depending on which error they are handling.

Here's the equivalent using the first two methods. The first is a mangled mess of if statements, and the second is spaghetti code:

  f = open(filename)
  if (f equals 0):
    if (error equals 2):
      print "cannot find "+filename
    elseif (error equals 5):
      print "no permission to open "+filename
    else:
      print "unknown error number "+error+" opening "+filename
    endif
  endif


  on error goto fileopenerrorhandler
  f = open(filename)
 
  (.. other stuff ..)

  fileopenerrorhandler:
    if (f equals 0):
      if (error equals 2):
        print "cannot find "+filename
      elseif (error equals 5):
        print "no permission to open "+filename
      else:
        print "unknown error number "+error+" opening "+filename
      endif
    endif

Name: Anonymous 2008-06-14 10:20

>>11

no, >>1,9 are the same person (me), don't know about the rest

Name: Anonymous 2008-06-14 10:26

>>12
if(f == 0) perror("shitty example program");

Name: Anonymous 2008-06-14 10:42

>>7
Because you wrote it.

Name: Anonymous 2008-06-14 11:07

>>9
yes call/cc is reentrant, i didn't know it's threadsafe though... care to point me to an example implementation?
Oh I was just kidding, no closures in C, no call/cc in C.

What this all really means, though, is that you, >>9, should just stick with errno.

Name: Anonymous 2008-06-14 11:42

>>16
err...
there is a way to implement call/cc in C:
[url]http://homepage.mac.com/sigfpe/Computing/continuations.html[/url]
or backtracking to be precise

also, as C is only a bit higher than ASM, everything you can do in higher level languages, you can do in C, it's just not so preety looking (as will, no doubt, pthread aware exception handling, so good luck >>9)

Name: Anonymous 2008-06-14 11:56

>>16
errno won't work with me, because i'm writing a network application and already use 15 line #define statements to recover from errors in transmission

of course you can do it with returns and else if's, but exceptions make the code much more readable, much more mangable and stack unwinding is trivial, now, to implement it with threads...

anyway, if i'm sucessful, i'll post the resulting .h in /prog/ (if it won't be too humongous)

Name: Anonymous 2008-06-14 12:15

>>15
You can't prove that.

Name: Anonymous 2008-06-14 12:29

goto is all the exception handling you need in c

Name: Anonymous 2008-06-14 13:03

I write my gotos with __asm

Name: Anonymous 2008-06-14 13:33

>>18
i'm writing a network application
Is there any specific reason why people still use C for applications instead of C++? I mean, even if you don't want to use classes, why not write C-style C++ so if you want to use exceptions or other C++ functions you have the opportunity to do it?

Name: Anonymous 2008-06-14 13:37

[url]
/prog/
^[a-z]
Sigh..

The code is actually good, but respecting C syntax, like try { ... } catch { ... } end_try; would be better.

Are there any reasons to avoid using this? Like longjmp() breaking portability or something, I don't know.

Name: Anonymous 2008-06-14 14:14

>>22
first i just like being near the metal and to exacly know what is happening when the code is executed

second, i like my programs as fast as possible without using ASM, a small fixation of mine

third, i found a benchmark somwhere on the web, the exception handling code in C was about 4-5% faster, that's statistically insignificant, but when the actual exceptions were thrown, the C code was more than 70 times faster than C++!

forth, but not as important, my code will be highly dynamical and i'd like not to expirience some of the horrors described in http://www.yosefk.com/blog/oo-c-is-passable.html

>>23
no, you can write it this way, it won't change anything

i wrote the exampe this way, just to make it look more high levelish to not intimidate ENTERPRISE JAVA PROGRAMMERS and show them, that C is, in fact, better

Name: Anonymous 2008-06-14 14:17

>>23
Actually, TRY, CATCH, FINALLY and END_TRY would be better, since macro names are conventionally written in allcaps. I think the { ... } would be overkill, though.

Name: Anonymous 2008-06-14 14:18

>>20,21
goto doesn't work between functions and retriving either results or error codes from functions through parameters is an ugly hack

6/10

Name: Anonymous 2008-06-14 14:34

>>1
you failed, it has been done before, better than you as well.
http://www.tendra.org/browser/trunk/libexds

Name: Anonymous 2008-06-14 14:58

>>24
The guy who wrote the anti-Sepples faq is a flaming idiot. His only point is basically "IT COMPILES FASTER HURR", but if you don't use any template and shit, the difference is unsignificant. Especially in a small, one-man project.

Most of the "FQA" is just straw men and loaded words. Like he calls something a "fiasco" to give off the impression that a feature is widely considered a disaster, even when it's absolutely not the case. You should always be skeptical of critics too, not just of proponents. There's a reason C++ is used a lot, and it's not "C++ programmers are retards who can't do C".

It doesn't matter, by the way, if exceptions are slow (and they are). You're only supposed to use them in exceptional cases, usually when user intervention is needed. If you're writing a function where failure is expected to happen often, C++ gives you various ways to do it: return a boolean flag, or if you already return stuff you can return a pair<data,bool> and then do if(pair.second){normalcode;}else{errorhandling;}, which isn't an ugly hack, and is hardly longer than a try/catch. You could also take a flag by reference and make it false if your function fails. You could make a function object which handles its own errors, or sets a flag if it couldn't recover (so in your main code you could do if(networkSenderWhatever->Failed()){blabla;} )

Name: Anonymous 2008-06-14 15:34

I prefer boost::optional<T>, but I agree. Similarly, the .NET Framework Guidelines recommend returning null instead of throwing an exception when failure is a common case1:
  ❝Return null for extremely common error cases. For example, Open returns null if the file is not found, but throws an exception if the file is locked.

References
1 SDN, M. Best Practices for Handling Exceptions. http://msdn.microsoft.com/en-us/library/seyhszts.aspx (Retrieved 14thJune, 2008)

Name: Anonymous 2008-06-14 15:56

>>28
Try reading the whole thing. Compilation times are only part of it.

Name: Anonymous 2008-06-14 15:59

boost::optional<T>
Interesting, thanks for the tip. I have to check out boost's doc more in-depth someday.

Name: Anonymous 2008-06-14 16:09

>>27

by my code will be thread safe as soon as i find 2h to write it (i have the solution thought out already) and libexds still isn't:
http://www.tendra.org/ticket/210

still, i'll look into it, maybe they have some intresting solution, but AFAICS it's more clunky (semantically-wise)

Name: Anonymous 2008-06-14 16:54

>>27
it passes down local variables as a means of memory allocation, neat i'd say, haven't thought of that

>>23
yes, macros, as a rule, are written in allcaps, but these are not suposed to be though as macros
va_start(), va_arg() and va_end() from stdarg(3) are macros too, and aren't written in allcaps, not to mention few dozen other "functions" from standard library...

Name: Anonymous 2008-06-14 17:04

>>24
second, i like my programs as fast as possible without using ASM, a small fixation of mine

Anonix detected!

Name: Anonymous 2008-06-14 17:11

>>33
But if you write them in allcaps, folks skimming through code that uses them will instantly know that they are dealing with macros, and will take less time to realize that the code is using homebrew exception handling. Plus they'll be less likely to blindly dismiss your implementation of exception handling if you stick to naming conventions.

Name: Anonymous 2008-06-14 17:25

>>35
well, I know of no ANSI C compiler supporting exceptions, so it won't be hard to notice that it's homebrew, as long as they know that it's C, not C++

and if they start messing with the code, they will quickly realise if they use them wrongly (because of mismatching parentheses during compilation)

if you really don't like it, change #defines if you use it, I like it better this way so I won't change it

Name: Anonymous 2008-06-14 17:36

>>36
Hey, just trying to help here. If you really don't like it, just hax my anus.

Name: Anonymous 2008-06-14 18:53

This thread is what's right with /prog

Name: Anonymous 2008-06-14 18:53

Er, or /prog/

Name: Anonymous 2008-06-14 19:12

>>38,39
Are you being sarcastic?

Name: >>38,39 2008-06-14 19:18

>>40

Half. The content of the thread itself isn't particularly good but some of the latest posts made me forget about the /prog/snake momentarily.

Name: Anonymous 2008-06-14 19:31

>>41
Come on, now you're being sarcastic.

Name: Anonymous 2008-06-14 19:34

>>29
That is fucking ugly. You'd have to check both return value and catch the possible exception always, otherwise, it crashes.

>>28
You've got a good point. Also, he admits in the linked post that he's a EXPERT SEPPLES TROLL. But I have been always avoiding sepples, and he's right in a few aspects. At least, when referring to the feature bloat. But trying to say that everything in the FAQ is wrong, that everything in the language is evil, is too much, and he clearly failed in that sense.

Name: Anonymous 2008-06-14 19:35

>>42
YHBT

Name: Anonymous 2008-06-14 19:39

>>14
It was just to illustrate a point.

Name: Anonymous 2008-06-14 20:18

>>43
ENTERPRISE BEST PRACTICES

Name: 28 2008-06-15 10:58

But trying to say that everything in the FAQ is wrong, that everything in the language is evil, is too much, and he clearly failed in that sense.
Exactly, and that's why I didn't feel like reading it all. It's going overboard when everything about C++ becomes a fiasco/bloat/piece of shit.

Anyway, I see you've given it some thought, so your decision must be well justified. . Enjoy your C, and your job

Name: Anonymous 2008-06-15 13:05

>>38
Except the faggotfuck >>37.
FUCK YOU FAGGOT. IT'S ONLY YOU WHO POSTS THAT CRAP. YOU'VE FAILED.

Name: Anonymous 2008-06-15 13:29

>>48
That was a bit excessive. That guy just had some problems in his childhood, like being raped by his parents. We must understand that all he wants is some loeb.

Disregard that, >>48 YHBT

Name: Anonymous 2008-06-15 14:21

>>49
loeb :: Functor f => f (f a -> a) -> f a
loeb f = fmap ($ loeb f) f

Name: Anonymous 2008-06-15 14:34

>>48
*grabs dick*

Name: Anonymous 2011-02-04 17:33

Name: Sgt.Kabukiman怮긡 2012-05-24 6:10

All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy

Name: bampu pantsu 2012-05-29 3:51

bampu pantsu

Don't change these.
Name: Email:
Entire Thread Thread List