Is this a good way for unconditional jump? - c

I have a function f( ) in a file func.c and functions f1( ), f2( ), f3() , f4( ) in another file funcs.h. (Assume that all the functions receive/return values without any loss of generality).
Function f( ) calls f4( )
f4( ) calls f1( ), f2( ), f3( ) in some arbitrary order, among themselves
At some point of time during the execution, f3() detects the completion of the algorithm and it has to "terminate" the execution of the algorithm. In a standalone case, it should exit out of the program after printing the solutions.But here, I need f3( ) to return to f( ).
This is my solution:
In this scenario, I cannot simply return to f4() (the original function called by f(), since there is already a function call stack of f1(), f2(), f3(),f4(), waiting to be "popped"). So, what I did is:
I did a setjmp( ) in f() before calling f4( )
And then, I did a longjmp( ) in f3( ) when I detected the completion of the algorithm
My question is: Is this the correct way to achieve this in this scenario?

TBH I personally find its better to return a bool from the function and if the return is true then return true from the function below and so on until it gets back to the original function. This unwinds the stack correctly, which im not sure setjmp/longjmp does.
In general though if you aren't going to go on and do stuff after the f() function returns it should work anyway. I'd just argue its not a very good way to do things as someone reading the code will not find it as obvious as the functions returning bool back up the stack.

You can use getcontext/setcontext. They may be viewed as an advanced version of setjmp/longjmp; whereas the latter allows only a single non-local jump up the stack, setcontext allows the creation of multiple cooperative threads of control, each with its own stack.
Also refer to other related calls such as makecontext(), swapcontext().
Here is one sample code to show how to use these functions (Sorry for bad coding). Hope this helps you.
#include <stdio.h>
#include <ucontext.h>
void func(void);
int x = 0;
ucontext_t context, *cp = &context;
int main(void) {
getcontext(cp);
if (!x) {
printf("getcontext has been called\n");
func();
}
else {
printf("setcontext has been called\n");
}
}
void func(void) {
x++;
setcontext(cp);
}
Output:
getcontext has been called
setcontext has been called

f4( ) calls f1( ), f2( ), f3( ) in some arbitrary order, among themselves
What do you mean by "arbitrary order"? Unless you're writing a multi-threaded program, the order in which 1,2, and 3 are called should be deterministic; functions are executed synchronously in C.

You didn't mention what you are doing or what algorithm are you implementing but...
You could use a global structure with function pointers which f1,f2,f3,f4 knows it existence and from f4() you call f1() doing something like:
global.functionPointers[0]("parameters.for.f1");

Don't you still need a flag to know that you shouldn't call f4 again the second time?
int solution_found=0;
f(){
setjmp();
if (!solution_found)
f4();
/* continue here... */
}
Apart from that, setjmp/longjmp may be expensive calls. They also have a price in terms of readability of your program. I would certainly consider having f1,... pop themselves out of the stack the normal way instead, if I was you.

I would do it something like this:
struct solution { ... }
solution *f() {
solution *result;
if (something) {
result = f3();
if (result != NULL)
return result;
}
else {
result = f3();
if (result != NULL)
return result;
}
return f();
}
Or whatever your algorithm might be.

Related

How can I go to the beginning of main function from a sub function in C programing language?

I am writing a C code, this code consist with many sub functions and also within a sub function there is another sub function after execution of this sub sub function I need to go back in the beginning of main function.
My question is how can I exit from this function and come back main function?
As this code is too big That is why I have not include this code in here.I think return; cant do this thing because it returns only to the function where it got function call. I am beginner in C programming so please suggest what thing I have to do for this?
THIS ANSWER NEEDS A HEALTH HAZARD - THIS IS THE WRONG WAY TO PROGRAM
You can use setjmp and longjmp to do this.
But PLEASE do everything in your power to avoid this - by thinking about the design of the code beforehand
C maintains a stack of nested functions. If your main program calls function one and that calls function two, you can only get back to the main program by unwinding the stack using a return statement in each function (therefore from two back to one, and then back to main). So I don't think you can do what you're wanting. You can terminate the program completely with the exit statement.
Jumping across function boundaries is contrary to structured programming, and while possible (using setjmp(), longjmp()) is inappropriate and unnecessary in this case.
You need not treat function calls as simple sub-routines - they take arguments and return values; the return value in particular is useful in this case for providing information to the caller for controlling program flow.
Based on your (somewhat confusing) diagram:
typedef enum tStatus
{
STATUS_FAIL ;
STATUS_SUCCESS ;
} tStatus;
void function1( void ) ;
tStatus function2( void ) ;
tStatus function1n( void ) ;
int main()
{
for(;;)
{
// statement1
// statement2
function1() ;
if( function2() == STATUS_SUCCESS )
{
// statement3
}
}
return 0 ;
}
void function1( void )
{
// do something
}
tStatus function2( void )
{
// statement1
// statement2
tStatus status = function1n() ;
if( status == STATUS_SUCCESS )
{
// statement n
}
return status ;
}
tStatus function1n( void )
{
tStatus status = STATUS_FAIL ;
// statement1
if( !condition)
{
status = STATUS_SUCCESS ;
// statement n
}
return status ;
}
If you follow the code flow, you will see that when in function1n() condition is true then STATUS_FAIL is returned to function2(), which returns STATUS_FAIL to main() which then causes control flow to return to the top of the main() loop.
Note that most simple bare-metal embedded systems do not return from main() so an indefinite loop is the normal implementation when no OS or RTOS is used.
Make the inner function return a value rather than void. Use that value in the middle function to determine if you should return to main.
int main(void) {
f2();
return 0;
}
void f2(void) {
if (f1()) return;
/* ... */
}
int f1(void) {
if (condition true) return 1;
/* ... */
return 0;
}

How to Pass Simple, Anonymous Functions as Parameters in C

I'm sure some variation of this question has been asked before but all other, similar questions on SO seem to be much more complex, involving passing arrays and other forms of data. My scenario is much simpler so I hope there is a simple/elegant solution.
Is there a way that I can create an anonymous function, or pass a line of code as a function pointer to another function?
In my case, I have a series of diverse operations. Before and after each line of code, there are tasks I want to accomplish, that never change. Instead of duplicating the beginning code and ending code, I'd like to write a function that takes a function pointer as a parameter and executes all of the code in the necessary order.
My problem is that it's not worth defining 30 functions for each operation since they are each one line of code. If I can't create an anonymous function, is there a way that I can simplify my C code?
If my request isn't entirely clear. Here's a bit of pseudo-code for clarification. My code is much more meaningful than this but the code below gets the point accross.
void Tests()
{
//Step #1
printf("This is the beginning, always constant.");
something_unique = a_var * 42; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
//Step #2
printf("This is the beginning, always constant.");
a_diff_var = "arbitrary"; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
...
...
//Step #30
printf("This is the beginning, always constant.");
var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
}
Not in the traditional sense of anonymous functions, but you can macro it:
#define do_something(blah) {\
printf("This is the beginning, always constant.");\
blah;\
printf("End code, never changes");\
a_var++;\
}
Then it becomes
do_something(something_unique = a_var * 42)
No, you cannot. Anonymous functions are only available in functional languages (and languages with functional subsets), and as we all know, c is dysfunctional ;^)
In C and pre-0x C++, no.
In C++0x, yes, using lambda functions.
The best way to simplify your code would probably to put a for loop around a switch statement.
int a_var;
for ( a_var = 0; a_var <= 30; a_var++ )
{
starteroperations();
switch (a_var)
{
case 0:
operation0(); break;
case ...:
operationx(); break;
case 30:
...
}
closingoperations();
}
If you can use Clang, you can take advantage of blocks. To learn blocks, you can use Apple's documentation, Clang's block language specification and implementation notes, and Apple's proposal to the ISO C working group to add blocks to the standard C language, as well as a ton of blog posts.
Using blocks, you could write:
/* Block variables are declared like function pointers
* but use ^ ("block pointer") instead of * ("normal pointer"). */
void (^before)(void) = void ^(void) { puts("before"); };
/* Blocks infer the return type, so you don't need to declare it
* in the block definition. */
void (^after)(void) = ^(void) { puts("after"); };
/* The default arguments are assumed to be void, so you could even
* just define after as
*
* ^{ puts("after"); };
*/
before();
foo = bar + baz*kablooie;
after();
This example gives the anonymous blocks names by assigning to a block variable. You can also define and call a block directly:
^{ puts("!"); } ();
/*| definition | invocation of anonymous function |*/
This also makes defining "struct-objects" (OOP in C using structs) very simple.
Both Clang and GCC support inner/nested functions as an extension to standard C. This would let you define the function immediately before taking its address, which might be an alternative if your control flow structure allows it: inner function pointers cannot be allowed to escape from their immediate scope. As the docs say:
If you try to call the nested function through its address after the containing function has exited, all hell will break loose. If you try to call it after a containing scope level has exited, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.
Using nested functions, you could write:
/* Nested functions are defined just like normal functions.
* The difference is that they are not defined at "file scope"
* but instead are defined inside another function. */
void before(void) { puts("before"); };
void after(void) { puts("after"); };
before();
foo = bar + baz*kablooie;
after();
Either you go the case way suggested by #dcpomero, or you do the following:
typedef void job(int);
job test1; void test1(int a_var) { something_unique = a_var * 42; }
job test2; void test2(int a_var) { a_diff_var = "arbitrary"; }
job test3; void test3(int a_var) { var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; }
job * tests[] = { test1, test2, test3, testn };
void Tests()
{
int i;
for (i=0; i < sizeof tests/sizeof tests[0]; i++) {
printf("This is the beginning, always constant.");
tests[i](a_var);
printf("End code, never changes");
a_var++;
}
}

exchange of control between functions in C language

Considering the following scenario:
fn(1) calls fn(2) , then
fn(2) calls fn(3), and now
fn(3) should pass the control to fn(1) instead of fn(2) and control must not come back again.
Regarding this I have tried with goto, but goto does not work between functions, its only a local jump.
I wanted to check if there is any other method I could use to send the control to another function
NOTE: NO global variable, pointer to functions will work in this case, as per my exploration
Well, the typical way of doing this would be:
int fn3() {
return 1;
}
void fn2() {
if (fn3())
return;
...
}
Not sure if you're looking for something more esoteric, such as setjmp/longjmp
You can use longjmp as a "long range goto" if you absolutely must do this.
int fn1(void) {
printf("in fn1 before calling fn2\n");
fn2();
printf("in fn1 after calling fn2\n");
return 0;
}
int fn2(void) {
printf("in fn2 before calling fn3\n");
if (1) {
return fn3();
}
printf("in fn2 after calling fn3\n");
return 0;
}
int fn3(void) {
printf("in fn3\n");
return 0;
}
You can use setjmp and longjmp to do this -- but it's almost certainly a really bad idea to actually do so. Former Fortran programmers (among others) still sometimes have nightmares about the kind of mess you seem intent on creating. Given a time when a mainframe that served 300+ simultaneous users ran at 20 MHz or so, there was some excuse at the time, even if keeping track of things was a mess. Given current computers, I question not only the utility but the very sanity of having a function call that doesn't return (especially since CPUs are now optimized for that case, so what you're asking for will be slower than normal returns).
What you try to implement are so called coroutines. While C doesn't directly support them, there are ways to exploit some ingenious hacks like Duff's Device to implement them.
Simon Tatham wrote an excellent article about Coroutines in C: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
I think you should use setjmp() and longjmp(). The man is available here.
The following example shows you how to use it (from http://en.wikipedia.org/wiki/Setjmp.h#Example_usage ):
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void first(void) {
second();
printf("first\n"); // does not print
}
int main() {
if ( ! setjmp(buf) ) {
first(); // when executed, setjmp returns 0
} else { // when longjmp jumps back, setjmp returns 1
printf("main\n"); // prints
}
return 0;
}
Output :
second
main

Exception Handling in C - What is the use of setjmp() returning 0?

I have a few questions relating to setjmp/longjmp usage -
What is the use of setjmp(jmp___buf stackVariables) returning 0. It is a default, which we cannot influence.
Is the only significance of setjmp(stackVariables) is to push the stack in stackVariables. And basically 0 tells us if the stack was pushed on stack_variables successfully.
Their is one occasion when the value is non-zero (any non-zero) when you return from a longjmp. What is returning from a lomgjmp, when do you return from longjmp, when your exception is handled. This is setup is really confusing.
Can some please relate it to try/throw and catch. And would be really great, if some good examples of setjmp/longjmp could be provided.
Is longJmp like throw, and it is called just after the place where exception can be raised.
Thanks.
The C99 spec gives:
If the return is from a direct invocation, the setjmp macro returns the value zero. If the
return is from a call to the longjmp function, the setjmp macro returns a nonzero
value.
So the answer to 1 is that a zero indicates you have called setjmp the first time, and non-zero indicates it is returning from a longjmp.
It pushes the current program state. After a longjmp, the state is restored, control returns to the point it was called, and the return value is non-zero.
There are no exceptions in C. It's sort-of similar to fork returning different values depending whether you're in the original process, or a second process which has inherited the environment, if you're familiar with that.
try/catch in C++ will call destructors on all automatic objects between the throw and the catch. setjmp/longjmp will not call destructors, as they don't exist in C. So you are on your own as far as calling free on anything you've malloced in the mean time.
With that proviso, this:
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
void foo ( char** data ) ;
void handle ( char* data ) ;
jmp_buf env;
int main ()
{
char* data = 0;
int res = setjmp ( env );
// stored for demo purposes.
// in portable code do not store
// the result, but test it directly.
printf ( "setjmp returned %d\n", res );
if ( res == 0 )
foo ( &data );
else
handle ( data );
return 0;
}
void foo ( char** data )
{
*data = malloc ( 32 );
printf ( "in foo\n" );
strcpy ( *data, "Hello World" );
printf ( "data = %s\n", *data );
longjmp ( env, 42 );
}
void handle ( char* data )
{
printf ( "in handler\n" );
if ( data ) {
free ( data );
printf ( "data freed\n" );
}
}
is roughly equivalent to
#include <iostream>
void foo ( ) ;
void handle ( ) ;
int main ()
{
try {
foo ();
} catch (int x) {
std::cout << "caught " << x << "\n";
handle ();
}
return 0;
}
void foo ( )
{
printf ( "in foo\n" );
std::string data = "Hello World";
std::cout << "data = " << data << "\n";
throw 42;
}
void handle ( )
{
std::cout << "in handler\n";
}
In the C case, you have to do explicit memory management (though normally you'd free it in the function which malloc'd it before calling longjmp as it makes life simpler)
setjmp is used to place a marker to where the call of longjump should return, it returns 0 if it is called directly, it returns 1 if it's called because a longjmp to that setjmp is invoked.
You have to think about setjmp like something that can be normally called and does not do anything (returning 0) in normal operation while returns 1 and it's indirectly called (and returns from there) when a long jump is called. I know what you mean about confusing because it's actually confusing..
This is the example given by wikipedia:
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void)
{
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void first(void)
{
second();
printf("first\n"); // does not print
}
int main()
{
if ( ! setjmp(buf) )
{
first(); // when executed, setjmp returns 0
}
else
{ // when longjmp jumps back, setjmp returns 1
printf("main"); // prints
}
return 0;
}
Are you able to understand it?
When program is launched setjmp is executed in main and returns 0 (because it is directly called), so first is called, that calls second and then it arrives longjmp that switches context going back to where setjmp was used, but this time, since it goes back from a jump and it is indirectly called the function returns 1.
The useful thing of setjmp/longjmp approach is that you can handle error situations without caring to keep a flag between function calls (especially when you have many, think about a recursive procedure for typechecking in a compiler). If something goes wrong in typechecking deep in call stack normally you have to return a flag and keep returning it to warn the caller that typechecking failed. With longjmp you just go out and handle error without caring about passing flags back. The only problem is that this forces a context switch that doesn't care about standard deallocation of stack/heap memory so you should handle it by yourself.
The first part is almost simple: When you do a longjmp, you end up exactly after the setjmp. If the return value is 0, it means you just did the setjmp; if it is nonzero, you know you got there from a longjmp from elsewhere. That information is often useful in controlling what your code does after that.
setjmp/longjmp are the old ancestors of throw/catch. setjmp/longjmp are defined in C, whereas throw/catch is the more "modern" mechanism for doing error recovery in more object-oriented languages like C++.
calling longjmp says: "I think there's something wrong here, help, get me out of here - I'm too confused to clean up after myself and return through a bunch of function calls and if's; just get me right back to where the world was OK again, right after the last setjmp."
throw says pretty much the same thing, except it's more clearly and cleanly supported in syntax. Also, while longjmp can take you to practically ANY place in the program (wherever you did the setjmp), throw ends up directly upward in the call hierarchy of where the throw is.
Just to add to the answer (and remark) by Pete Kirkham: since C standard does not allow storing the return value of setjmp, perhaps Pete's example could be changed to use switch instead. It still demonstrates how to distinct between different return values but does not violate the standard.
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
void foo(char** data) ;
void handle(char* data) ;
jmp_buf env;
int main(void)
{
char* data = 0;
switch(setjmp(env))
{
case 0:
{
printf("setjmp returned 0\n");
foo(&data);
break;
}
case 42:
{
printf("setjmp returned 42\n");
handle ( data );
break;
}
default:
{
printf("setjmp returned something else?\n");
}
}
return 0;
}
void foo(char** data)
{
*data = malloc(32);
printf("in foo\n");
strcpy(*data, "Hello World");
printf("data = %s\n", *data);
longjmp(env, 42);
}
void handle(char* data)
{
printf("in handler\n");
if(data)
{
free(data);
printf("data freed\n");
}
}

How to call a function just before returning in C?

I'm trying to execute something at the end of a function just before it returns to the caller.
To Do so, I would like to override return in a certain context. The behavior should be the same as __cyg_profile_func_exit, but I would like to activate it only for some functions.
I don't know if it's possible using gcc builtins or this kind of thing.
Thanks.
GCC has an attribute for this, which calls a function when an automatic variable goes out of scope, passing it the address of that variable
void cleanup_fn(int *p) {
puts("cleanup called...");
}
void f(void) {
int p __attribute__((cleanup(cleanup_fn)));
puts("in f...");
}
int main(void) {
puts("calling f...");
f();
puts("out of it...");
return 0;
}
Output:
calling f...
in f...
cleanup called...
out of it...
Nope, not in C per se.
What you could do is write a #define macro RETURN:
#define RETURN(func) if(_DEBUG_) func; return ;
#define RETURNV(func, val) if(_DEBUG_) func; return val ;
(Warning, you probably want to think a little more about guarding special cases than I have.)
Otherwise, you would need to write something that mangled the code behind the scenes, which is what profilers do.

Resources