473,327 Members | 1,936 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,327 software developers and data experts.

Need experts opnion

Hi all,
In my current project I am thinking to use setjmp/lngjmp for exception
handling.The way I am planing to do this is shown in the below example.
Please if this is the right way to do.Are there any disadvantages in
this method?

#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
jmp_buf g_env;
extern void fun1();
int main()
{
int ret;

ret = setjmp(g_env);
if (ret == 0)
{
printf("Perform the intended functionality");
fun1();
exit(EXIT_SUCCESS);
}
else
{
printf("Exception handling\n");
exit(EXIT_FAILURE);
}

}
#include <stdio.h>
#include <setjmp.h>

extern jmp_buf g_env;

void fun1()
{
longjmp(g_env,1);
}

Jan 5 '06 #1
18 1321
va******@rediffmail.com wrote:
Hi all,
In my current project I am thinking to use setjmp/lngjmp for exception
handling.The way I am planing to do this is shown in the below example.
Please if this is the right way to do.Are there any disadvantages in
this method?

#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
jmp_buf g_env;
extern void fun1();
int main()
{
int ret;

ret = setjmp(g_env);
if (ret == 0)
{
printf("Perform the intended functionality");
fun1();
exit(EXIT_SUCCESS);
}
else
{
printf("Exception handling\n");
exit(EXIT_FAILURE);
}

}
#include <stdio.h>
#include <setjmp.h>

extern jmp_buf g_env;

void fun1()
{
longjmp(g_env,1);
}


Hi,

Starting with the code you has post, there are several posible
improvements:

1) Do not use a single jmp_buf, but an array of it.
2) Define macros to made more visible the exception handling. Only as
an example:

#define TRY if (setjmp(g_env))
#define CATCH else
#define THROW(x) longjmp(g_env,x)

mades the code

TRY
{
}
CATCH
{
}

....
THROW(1)

3) Do not forget the falg volatile when necessary.

Kind regards.

Jan 5 '06 #2

tmp123 wrote:
1) Do not use a single jmp_buf, but an array of it.


Could you please explain in detail why jmp_buf should be an array?

Jan 5 '06 #3
va******@rediffmail.com wrote:

In my current project I am thinking to use setjmp/lngjmp for
exception handling.The way I am planing to do this is shown in
the below example. Please if this is the right way to do.Are
there any disadvantages in this method?
*** quote munged to reduce vertical space *** #include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
jmp_buf g_env;
extern void fun1();
int main()
{
int ret;

ret = setjmp(g_env);
if (ret == 0) {
printf("Perform the intended functionality");
fun1();
exit(EXIT_SUCCESS);
}
else {
printf("Exception handling\n");
exit(EXIT_FAILURE);
}
}

#include <stdio.h>
#include <setjmp.h>

extern jmp_buf g_env;

void fun1()
{
longjmp(g_env,1);
}


Surprise. Your very first statement "ret = setjmp(...)" is
illegal! The following is a quote from N869:

Environmental limits

[#4] An invocation of the setjmp macro shall appear only in
one of the following contexts:

-- the entire controlling expression of a selection or
iteration statement;

-- one operand of a relational or equality operator with
the other operand an integer constant expression, with
the resulting expression being the entire controlling
expression of a selection or iteration statement;

-- the operand of a unary ! operator with the resulting
expression being the entire controlling expression of a
selection or iteration statement; or

-- the entire expression of an expression statement
(possibly cast to void).

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 5 '06 #4

Chuck F. wrote:
Surprise. Your very first statement "ret = setjmp(...)" is
illegal! The following is a quote from N869:

Environmental limits

[#4] An invocation of the setjmp macro shall appear only in
one of the following contexts:

-- the entire controlling expression of a selection or
iteration statement;

-- one operand of a relational or equality operator with
the other operand an integer constant expression, with
the resulting expression being the entire controlling
expression of a selection or iteration statement;

-- the operand of a unary ! operator with the resulting
expression being the entire controlling expression of a
selection or iteration statement; or

-- the entire expression of an expression statement
(possibly cast to void).

I am not able to understand any of these points. Can anybody explain in
simpler way(if possible with an example)?
Thanks in Advance

Jan 5 '06 #5

va******@rediffmail.com wrote:
tmp123 wrote:
1) Do not use a single jmp_buf, but an array of it.


Could you please explain in detail why jmp_buf should be an array?


If you have an array of similar, you can have nested TRYs, in same or
different procedures.

Kind regards.

Jan 5 '06 #6
va******@rediffmail.com wrote:
Chuck F. wrote:
Surprise. Your very first statement "ret = setjmp(...)" is
illegal! The following is a quote from N869:

Environmental limits

[#4] An invocation of the setjmp macro shall appear only in
one of the following contexts:

-- the entire controlling expression of a selection or
iteration statement;

-- one operand of a relational or equality operator with
the other operand an integer constant expression, with
the resulting expression being the entire controlling
expression of a selection or iteration statement;

-- the operand of a unary ! operator with the resulting
expression being the entire controlling expression of a
selection or iteration statement; or

-- the entire expression of an expression statement
(possibly cast to void).

I am not able to understand any of these points. Can anybody explain in
simpler way(if possible with an example)?
Thanks in Advance


You are not allowed to do something like
ret = setjmp(...);
You should do something like:
if (setjmp(...)...)
or:
if (!setjmp(...))
or:
switch (setjmp(...)) {
...
}
You can also just have a line:
setjmp(...);
I.e. not using the value returned.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 5 '06 #7
In article <11**********************@g44g2000cwa.googlegroups .com>,
va******@rediffmail.com wrote:
Hi all,
In my current project I am thinking to use setjmp/lngjmp for exception
handling.The way I am planing to do this is shown in the below example.
Please if this is the right way to do.Are there any disadvantages in
this method?


One problem with any kind of exception handling is that exceptions
thrown will return to the exception handling code, skipping all function
calls in between. Any cleanup that is required by functions between the
initial caller and the place where the exception is thrown will not be
executed.

In Java, this problem is partially solved by having garbage collection.
Just organise your code so that throwing away dynamically allocated
objects will be enough to clean up. In C++, this problem is partially
solved by having destructors. Just organise your code so that
destructing any objects on the stack will be enough to clean up. In C,
there is no such thing. Any cleanup has to be done manually. You will
find yourself in major trouble very soon.

Unless you want to put superhuman effort into exception handling, the
only thing you can do in C is using setjmp/longjmp to cover complete
major subsystems; allocating all memory through functions that keep
track of allocation and free all memory when an exception happens,
installing function pointers for cleanup when necessary. This is a major
operation that needs experienced and diligent programmers.
Jan 5 '06 #8
Christian Bau wrote:
In article <11**********************@g44g2000cwa.googlegroups .com>,
va******@rediffmail.com wrote:
Hi all,
In my current project I am thinking to use setjmp/lngjmp for exception
handling.The way I am planing to do this is shown in the below example.
Please if this is the right way to do.Are there any disadvantages in
this method?


One problem with any kind of exception handling is that exceptions
thrown will return to the exception handling code, skipping all function
calls in between. Any cleanup that is required by functions between the
initial caller and the place where the exception is thrown will not be
executed.

In Java, this problem is partially solved by having garbage collection.
Just organise your code so that throwing away dynamically allocated
objects will be enough to clean up. In C++, this problem is partially
solved by having destructors. Just organise your code so that
destructing any objects on the stack will be enough to clean up. In C,
there is no such thing. Any cleanup has to be done manually. You will
find yourself in major trouble very soon.

Unless you want to put superhuman effort into exception handling, the
only thing you can do in C is using setjmp/longjmp to cover complete
major subsystems; allocating all memory through functions that keep
track of allocation and free all memory when an exception happens,
installing function pointers for cleanup when necessary. This is a major
operation that needs experienced and diligent programmers.

I agree on the previous (the reference to Java memory handling could be
completed with some security issues? and nested tries must be
referenced?).

However, the advantages of exceptions are also important. (Well, in
fact, nobody doubts today about benefits of exceptions, so, I'm being
redundant)

See two examples of a usual code with an without:

char * getLine( void )
{
FILE *f=NULL;
char *r=NULL;

if ( (r=malloc_string() == NULL ) return NULL;
if ( (f=file_open() == NULL )
{
/* Mixed messages and code!*/
fprintf(stderr, "unable to alloc...);
free(r);
return NULL;
}
if ( fgets(...) ... )
{
fprintf(stderr, "unable to ...);
free(r);
fclose(f); /* error handling grows! */
return NULL;
}
...
fclose(f);
return r;
}

char * getLines( const char *name )
{
FILE *f=NULL;
char *r=NULL;

TRY
{
f=file_open();
r=malloc_string();
if ( fgets(...) ... ) THROW(EXC_FAIL_READ);
...
fclose(f);
}
CATCH
{
if ( f != NULL ) fclose(f);
if ( r != NULL ) free(r);
r = NULL;
/* write errro messages or keep it in the main TRY */
THROW_NEXT;
}
END_TRY
return r;
}

Jan 6 '06 #9
tmp123 wrote:
.... snip ...
However, the advantages of exceptions are also important. (Well,
in fact, nobody doubts today about benefits of exceptions, so,
I'm being redundant)

See two examples of a usual code with an without:

char * getLine( void )
{
FILE *f=NULL;
char *r=NULL;

if ( (r=malloc_string() == NULL ) return NULL;
if ( (f=file_open() == NULL )
{
/* Mixed messages and code!*/
fprintf(stderr, "unable to alloc...);
free(r);
return NULL;
}
if ( fgets(...) ... )
{
fprintf(stderr, "unable to ...);
free(r);
fclose(f); /* error handling grows! */
return NULL;
}
...
fclose(f);
return r;
}


Here is my rewrite of that:

char * getLine(void)
{
FILE *f = NULL;
char *r, *rv = NULL;

if (!(r = mallocstring())) fprintf(stderr, "alloc..");
else if (!(f = file_open()) fprintf(stderr, "file ..");
else if (!fgets(...)) fprintf(stderr, "read ...");
else {
rv = r;
....
}
if (!rv) free(r);
if (f) fclose(f);
return rv;
}

(which I believe has the identical function, and has a single point
of return.) In practice I would probably postpone the malloc until
I had determined that the file would open.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 6 '06 #10
Christian Bau wrote:
In article <11**********************@g44g2000cwa.googlegroups .com>,
va******@rediffmail.com wrote:

Hi all,
In my current project I am thinking to use setjmp/lngjmp for exception
handling.The way I am planing to do this is shown in the below example.
Please if this is the right way to do.Are there any disadvantages in
this method?

One problem with any kind of exception handling is that exceptions
thrown will return to the exception handling code, skipping all function
calls in between. Any cleanup that is required by functions between the
initial caller and the place where the exception is thrown will not be
executed.

In Java, this problem is partially solved by having garbage collection.
[...]


And more thoroughly solved by the try/finally construct.
The lack of something analogous is what makes exception-like
constructs in "plain C" vulnerable to the problem you describe.
Solving the problem in "plain C" isn't impossible, but involves
more than simply calling setjmp() and longjmp() -- for example,
you'll need to be able to form chains of contexts so an exception
thrown in f() can cause cleanup actions in e() and d() and c()
and b() before being caught in a(). The machinery to manage the
context chains needn't be elaborate, but must be carefully crafted.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jan 6 '06 #11
In Java, this problem is partially solved by having garbage collection.
Just organise your code so that throwing away dynamically allocated
objects will be enough to clean up.


If I intialize all the pointers used for allocating memory to NULL and
call free on all these pointers uppon exception, then I have cleaned up
successfully is'nt it?

Jan 7 '06 #12
In article <11*********************@g14g2000cwa.googlegroups. com>,
va******@rediffmail.com wrote:
In Java, this problem is partially solved by having garbage collection.
Just organise your code so that throwing away dynamically allocated
objects will be enough to clean up.


If I intialize all the pointers used for allocating memory to NULL and
call free on all these pointers uppon exception, then I have cleaned up
successfully is'nt it?


But how do you do this? (Code is just for illustration, no guarantee
that it compiles or works)

void function_throwing_exception ()
{
longjmp (jmpbuf, 1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}

void caller ()
{
jmp_buf jmpbuf;
if (setjmp (jmpbuf))
{
function_in_the_middle ();
}
}

Now tell me how you clean up p, q and r when the exception is thrown.
Jan 7 '06 #13
>
But how do you do this? (Code is just for illustration, no guarantee
that it compiles or works)

void function_throwing_exception ()
{
longjmp (jmpbuf, 1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}

void caller ()
{
jmp_buf jmpbuf;
if (setjmp (jmpbuf))
{
function_in_the_middle ();
}
}

Now tell me how you clean up p, q and r when the exception is thrown.


As some others person have said, nested TRYs. Nothing new, same than in
C++ and others. Something more or less like:

void function_throwing_exception ()
{
THROW(1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

TRY
{
p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}
CATCH
{
free (r);
free (q);
free (p);
THROW_BACKWARD;
}
}

void caller ()
{
TRY
{
function_in_the_middle ();
}
...
}

My conclusion about this subject: use C++ compilers, even if the
keyword "class" is not used, except if no available or other hard
specification restrictions.

Jan 7 '06 #14
va******@rediffmail.com wrote:
In Java, this problem is partially solved by having garbage
collection. Just organise your code so that throwing away
dynamically allocated objects will be enough to clean up.


If I intialize all the pointers used for allocating memory to
NULL and call free on all these pointers uppon exception, then I
have cleaned up successfully is'nt it?


No. You also have to invert the order of allocation. Think of
linked lists or trees.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 7 '06 #15
In article <11**********************@g49g2000cwa.googlegroups .com>
tmp123 <tm****@menta.net> wrote:
My conclusion about this subject: use C++ compilers, even if the
keyword "class" is not used, except if no available or other hard
specification restrictions.


And what happens when you use a C++ compiler on the following
C program? (Note, it is stripped-down to make the problem more
apparent. If the problem is not immediately obvious, compile it
as both C and C++ and run both versions.)

#include <stdio.h>

struct A { char a[100]; };

int main(int argc, char **argv) {
struct B { struct A { char a; } b; } b;

printf("sizeof(struct A) = %lu\n",
(unsigned long)sizeof(struct A));
return 0;
}

(Although this particular example is stripped-down and looks
contrived, this was actually a real issue in a real program
in which someone carelessly attempted to mix C and C++ code.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 7 '06 #16
"tmp123" <tm****@menta.net> wrote:
void function_throwing_exception ()
{
THROW(1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

TRY
{
p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}
CATCH
{
free (r);
free (q);
free (p);
THROW_BACKWARD;
}
}

void caller ()
{
TRY
{
function_in_the_middle ();
}
...
}

My conclusion about this subject: use C++ compilers, even if the
keyword "class" is not used, except if no available or other hard
specification restrictions.


"Good" advice... since the code above does not compile under C++,
because that language is broken-as-designed where void * is involved.

Richard
Jan 9 '06 #17

Richard Bos wrote:
"tmp123" <tm****@menta.net> wrote:
void function_throwing_exception ()
{
THROW(1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

TRY
{
p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}
CATCH
{
free (r);
free (q);
free (p);
THROW_BACKWARD;
}
}

void caller ()
{
TRY
{
function_in_the_middle ();
}
...
}

My conclusion about this subject: use C++ compilers, even if the
keyword "class" is not used, except if no available or other hard
specification restrictions.


"Good" advice... since the code above does not compile under C++,
because that language is broken-as-designed where void * is involved.

Richard


Also "..." can cause problems, and the lack of definition for TRY, and
others.
It is somekind of joke?

Jan 10 '06 #18
"tmp123" <tm****@menta.net> wrote:
Richard Bos wrote:
"tmp123" <tm****@menta.net> wrote:
void function_throwing_exception ()
{
THROW(1);
}

void function_in_the_middle ()
{
char* p = NULL;
char* q = NULL;
char* r = NULL;

TRY
{
p = malloc (100);
q = malloc (100);
r = malloc (100);
function_throwing_exception ();
free (r);
free (q);
free (p);
}
CATCH
{
free (r);
free (q);
free (p);
THROW_BACKWARD;
}
}

void caller ()
{
TRY
{
function_in_the_middle ();
}
...
}

My conclusion about this subject: use C++ compilers, even if the
keyword "class" is not used, except if no available or other hard
specification restrictions.


"Good" advice... since the code above does not compile under C++,
because that language is broken-as-designed where void * is involved.


Also "..." can cause problems, and the lack of definition for TRY, and
others.


Those can be corrected with good C code. The point I refer to cannot.

Richard
Jan 10 '06 #19

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

Similar topics

0
by: samir dsf | last post by:
hi i have pasted page_load, my bindgrid, sort and itemdatabound event. my sorting in not working properly...i tried a couple of ways but there is something i am missing. pls suggest me on this...
68
by: Gsec | last post by:
Hi, Can anybody let me know how to write a infinite loop, such that the program never crashes ? I, guess, buffer overflow method mite help!Not sure. Plz let me know. -thanks and regards,
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
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: 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: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
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.