Any jump with return instruction in C? - c

I have multiple locations in my code where I want to be able to jump to one specific location and return to where I was before.
A function calls provides that control flow but is not an option for me as I want the code I branch to to access a number of variables and passing all of them as arguments to the function call wouldn't be practical or efficient.
And the goto statement is only built to take a label, i.e. expected to be a one-way ticket.
Currently I am achieving what I need with the following:
void *return_addr;
int x,y;
...
return_addr=&&RETURN_0;
goto SOMEWHERE;
RETURN_0:
...
x+=1;
...
return_addr=&&RETURN_1;
goto SOMEWHERE;
RETURN_1:
...
SOMEWHERE:
y=x;
...
goto *return_addr;
Is there something more elegant and less cumbersome?

Is there something more elegant and less cumbersome?
You are obviously using GCC, as the computed goto statement is a GCC extension. With GCC we can use a nested function and access local variables without needing to pass them as arguments:
{
int x, y;
void SOMEWHERE()
{
y = x;
//...
}
//...
SOMEWHERE();
//...
x += 1;
//...
SOMEWHERE();
//...
}

Let's have the variables collected in a structure:
struct data_t {
int a;
int b;
/* and so on */
int x;
int y;
};
Let's have the repeated code defined in a function:
void func(struct data_t* data) {
data->y = data->x;
/* and so on */
}
Let's have the function used:
struct data_t data = {1, 2, ..., 24, 25};
func(&data);
data.x += 1;
func(&data);
/* and so on */

C has setjmp() / longjmp(), which can support what you describe. Do not use them. Even more, however, do not rely on your current approach, which is not standard C, and which is terribly poor form.
What you describe is what functions are for. If you have a lot of data that you must share between the caller and callee, then either
record them in file-scope variables so that both functions can access them directly, or
create one or more complex data types (presumably structs) with which to hold and organize the data, and give the callee access by passing a pointer to such a struct.

A state machine can be written like this:
typedef enum { start, stop, state1, ... } state;
state s = start;
while (s != stop) {
switch (s) {
case start:
do_stuff; // lots of code
// computed goto
s = cond ? state23 : state45;
break;
...
Need a call stack?
state stack[42]; int sp=0;
...
do_stuff;
stack[sp++] = state33;
s = state45; // call
break;
case state33:
case state45:
do_processing; // some code
s = stack[--sp]; // ret
break;
You should only do this after you benchmark your time-critical code sections and find that the normal function call mechanism is indeed the bottleneck.

Related

using function names as functions in a C macro

Suppose i have code like this in my program:
if (!strcmp(current, "sin")) {
pushFloat(sin(x), &operands);
} else if (!strcmp(current, "cos")) {
pushFloat(cos(x), &operands);
} else if (!strcmp(current, "tan")) {
pushFloat(tan(x), &operands);
} else if (!strcmp(current, "ctg")) {
pushFloat(1. / tan(x), &operands);
} else if (!strcmp(current, "ln")) {
pushFloat(log(x), &operands);
} else if (!strcmp(current, "sqrt")) {
pushFloat(sqrt(x), &operands);
}
There are function names such as "sin" or "cos" saved in the current char array
Instead of using this long if block, or replacing it with an even longer switch block, i wanted to write a simple macro like this: #define PUSHFUNC(stack, func, value)(pushFloat(func(value), &stack)) and call it like this PUSHFUNC(operands, current, x)
Doing it this way creates an error "current is not a function or function pointer". I initially thought macros are just text replacement, so if i force a string that is equal to an actual function into a macro, it would expand to the function itself, but looks like i was wrong. Is there a way to achieve what i want using a macro, or should i just write a map block?
I initially thought macros are just text replacement,
That's your problem: macros are just text replacement. So if you have:
#define PUSHFUNC(stack, func, value) (pushFloat(func(value), &stack))
And you write:
PUSHFUNC(operands, current, x)
You get:
(pushFloat(current(value), &operands))
And indeed, you have no function named current. Macros are expanded before your code compiles; the preprocessor has no knowledge of the content of your variables.
If you really want to avoid a long chain of if statements, you could implement some sort of table lookup:
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
typedef double (*floatop)(double x);
typedef struct {
char *name;
floatop operation;
} entry;
double ctg(double);
entry opertable[] = {
{"sin", sin},
{"cos", cos},
{"tan", tan},
{"ctg", ctg},
{"sqrt", sqrt},
{NULL, NULL},
};
double ctg(double x) {
return 1. / tan(x);
}
floatop findop(char *name) {
int i;
for (i=0; opertable[i].name; i++) {
if (strcmp(opertable[i].name, name) == 0) {
return opertable[i].operation;
}
}
}
int main() {
float x = 4;
printf("sin(%f) = %f\n", x, findop("sin")(x));
printf("sqrt(%f) = %f\n", x, findop("sqrt")(x));
printf("tan(%f) = %f\n", x, findop("tan")(x));
printf("ctg(%f) = %f\n", x, findop("ctg")(x));
}
...but this requires that all of your functions take the same arguments, so for things like ctg you would need to add a helper function. You also need to decide if the increased complexity of the table lookup makes sense: it really depends on how many different operation names you expect to implement.
The output of the above code is:
sin(4.000000) = -0.756802
sqrt(4.000000) = 2.000000
tan(4.000000) = 1.157821
ctg(4.000000) = 0.863691
Is there a way to achieve what i want using a macro, or should i just write a map block?
I would recommend using an enum containing symbols for all the functions you might want to call, and using that in a switch-case block, instead of comparing a bunch of strings. Here's a very brief sample that only uses some of the functions you refer to...
enum which_func { SIN, COS, TAN, };
enum which_func which = SIN;
switch (which) {
case SIN:
pushFloat(sin(x), &operands);
break;
case COS:
pushFloat(cos(x), &operands);
break;
case TAN:
pushFloat(tan(x), &operands);
break;
default:
assert(false); // shouldn't be reachable if enum value is well-defined
}
This version will be easier to maintain in the long run, more efficient to execute and possibly more robust to logic errors (there are some compiler warnings that you can enable which will warn you if you're not handling all enum values, which can help you catch missed cases in your logic).
To add to what other answers said, what you can do is to make a macro that expands to the "basic block" of your if chain, avoiding some repetitions thanks to the stringizing operator:
#define HANDLE_FN_EXPR(fn, expr) \
else if(!strcmp(current, #fn)) \
pushFloat((expr), &operands)
#define HANDLE_FN(fn) \
HANDLE_FN_EXPR(fn, fn(x))
Then you can do
if(0);
HANDLE_FN(sin);
HANDLE_FN(cos);
HANDLE_FN(tan);
HANDLE_FN_EXPR(ctg, 1./tan(x));
HANDLE_FN(ln);
HANDLE_FN(sqrt);
Macros do in fact do text replacement. Given your macro definition, this:
PUSHFUNC(operands, current, x)
expands to this:
(pushFloat(current(x), &operands))
So as you can see, the text that is being replaced is the name of the variable, not the text that it contains.
And even if this did work as you expected, it wouldn't be able to properly handle the 1. / tan(x) case.
This means there isn't really a better way to do what you want.
Why not create some objects for each function type? I know, this is C not C++, but the idea will still work. First, create the function object type:-
typedef struct _Function
{
char *name;
float (*function) (float argument);
} Function;arg
And now create an array of function objects:-
Function functions [] =
{
{ "sin", sin },
{ "cos", cos }
// and so on
};
where the functions are defined:-
float sin(float x)
{
return 0; // put correct code here
}
float cos(float x)
{
return 0; // put correct code here
}
Finally, parse the input:-
for (int i = 0; i < sizeof functions / sizeof functions[0]; ++i)
{
if (strcmp(functions[i].name, current) == 0)
{
pushFloat(functions[i].function(arg)); // add operands!
break;
}
}
I find using enums for stuff like this very hard to maintain! Adding new functions means going through the code to find cases where the enum is used and updating it prone to errors (like missing a place!).
All because it's not C++, doesn't mean you can't use objects! It's just there's no language support for it so you have to do a bit more work (and, yeah, there are features missing!)

switch cases and one global variable for each case

I am dealing with a issue with switch cases.
Explanation of the program:
main(argc,argv).
argv leads to cases in a switch statement. Depending on the input, the according case will be entered and the corresponding function will be executed. -> Output is always a struct, with different content. More than one input (i.e. main.c case1 case3) is allowed-> executed both cases.
my problem is dealing with the passing of these data's and save it in a global variable, in order to print the collection. Inside of a case, I am passing the local results to the global variable, but after the break statement of the case, the global starts with NULL again and doesn't contain the info's of the executed case.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "m.h"
output* print;
int main(int argc, char* argv[])
{
output_g* global; // global_struct
if(argc > 1)
{
global= create_global(argc-1); // allocation for global struct
for(int j = 0; j < argc; j++)
{
switch (atoi(argv[i]))
{
case 123:
{
output* print= 123();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 456:
{
output* print= 456();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 789:
{
lfnr++;
output_1* print_liste = 789();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
default:
break;
}
print_global_struct(file,globale_liste);
delete_global(globale_liste);
}//End for-Schleife
}// End If
return 0;
}
a) If I understood you correctly, you don't understand the switch statement :)
A switch statement is similar to nested if statements.
so..
int x = 10;
switch (x)
case 1:
//does not happen, x is not 1
case 10:
//happens ...
after all that x is still 10, unless you changed it in the case statements explicitly. The cases just check to see IF x is a value, it does not SET a value. The same is true for any other variable in your code, the above code would not modify y either, unless you explicitly assign it inside a case it won't change.
b) it is best if you DO NOT declare locals in a case statement. They can become very wonky. The standard c++ rules work: variables declared inside {} pairs are scoped to inside that {} pair, so proper use of them will properly give the correct scope for each case. So it will work as expected if you apply braces. You should NOT declare a local in one case and use it in another, even if you can get it working (you can) it is error prone in that editing the code later can break things, the code can be confusing to read and work with, and its just generally a bad idea.
an example:
int main()
{
int x = 3;
switch(x)
{
case 1: int y;
case 2: y = 3;
case 3: y = 5;
cout << y << endl;
};
}
that compiled and ran for me, printing 5.
It worked fine -- I did not expect that, using g++ c17 options.
I still think it is a bad thing to do as far as reading and following the intent.
if you put {} around the int y statement, it does NOT compile anymore.
If you put breaks after the case 1 and case 2, it does NOT compile anymore.
so it is 'fragile' to being edited, at the very least, to do this.
c) run time won't lose anything. Ive had programs that ran for months on end. Being in a case has no effect on this either. The risk of losing variables is the 'ram' risk that all programs face... if a long running program is killed by power outage or malfunction etc you lose anything not saved to a file and have to start over. Long running programs should save their state periodically to protect against this.

Accessing label address outside of function

I'm writing "threaded interpreter" using computed goto. How do I initialize address lookup table to be visible from different functions without additional runtime cost?
Label address is only visible at same function and static lookup table is initialized by compiler in data section without runtime cost at each call. But it's visible only in same function and I want to have another function to have access to it, for example to cache addresses and save lookups in main interpreter code. I can take pointer to this table and store it somewhere, but it will happen every time function is called, and it will get called frequently. Yes, it's just only one mov, but is there another way?
#include <stdio.h>
static void** table_ptr;
// how do i declare static variable and init it later once?
// Tried this. Generates runtime assigns at each call. Not unexpected
// static void** jumps_addr;
int main()
{
// labels are visible only inside the function
// generates runtime assigns at each call
// jumps_addr = (void* [10]){
// this initializes it in static data section, but name is only visible inside this function
static void* jumps_addr[10] = {
[1] = &&operation_print,
};
// want another way instead of this
table_ptr = jumps_addr;
// not optimize this
volatile int opcode = 1;
goto *jumps_addr[opcode];
return 0;
operation_print:;
printf("hello\n");
return 0;
}
void do_some_preprocessing_work(void){
// want access to jumps_addr table here
// without having to store it somewhere
// [do something with table_ptr]
// this is to prevent optimization to explore what compiler does on godbolt.org
// because it will optimize away table_ptr entirely if not used
volatile i = 1;
i += table_ptr[i];
//actual code here will store labbel addrs into opcode struct to save table lookup at runtime
}
The solution might sound unorthodox, but how about not to use any functions, but only goto.
Like so:
#include <stdio.h>
int main()
{
volatile int opcode;
static void* jumps_addr[10] = {
[0] = &&do_some_preprocessing_work,
[1] = &&operation_print
};
opcode = 0;
goto *jumps_addr[opcode];
return 1;
operation_print:
printf("hello\n");
return 0;
do_some_preprocessing_work:
printf("jumps_addr[%i]\n", ++opcode);
goto *jumps_addr[opcode];
return 1;
}

"Fake" OOP in C - how to deal with destructors and fake function epilogues on returning

I am doing some experiments with faking OOP in C, and I've stumbled upon a conundrum. In C++ I assume the compiler inserts destructors in the function epilogue, after the return statement has been executed.
Faking that in C would require the destructors be manually invoked in the appropriate order, but the problem is the return value might depend on some of those objects, so at one hand destruction cannot occur before the return statement, on the other hand statements after the return statements are never reached. And the issue becomes more complicated by the fact there might be multiple return statements from inside different blocks which require their own respective fake epilogues.
So the question is how can I possibly deal with it? It doesn't have to be nice, since it doesn't look like it can be...
So far the best I could come up was to "cache" the return value at the moment of its return, do all the cleanup and after all that simply return the cached value, but I wonder if a a more efficient solution might exist, and on a side note on how well the compiler will deal with this one to minimize its eventual overhead. Sort of:
T foo() {
T _retValue;
...
if (something) {
...
_retValue = someValue;
goto blockID_cleanup;
blockID_cleanup:
...
goto foo_cleanup; // goto parent block until function block
}
_retValue = somethingElse;
goto foo_cleanup;
foo_cleanup:
...
return _retValue;
}
Edit: Seems you're actually asking how objects are returned from functions, your question isn't 100% clear but here goes:
class A
{
public:
A(int value)
: mTest(value) {}
A operator + (const A& other)
{
return mTest + other.mTest;
}
operator int()
{
return mTest;
}
private:
int mTest = 0;
};
int foo()
{
A a(2);
A aa(4);
return a + aa;
}
This would become the following pesudo code:
int foo()
{
A a;
A aa;
a_ctor(&a, 2);
a_ctor(&aa, 4);
A temp;
a_copy(temp, a_operator_plus(a, aa)); // temp is another "instance"
// no need to worry about the dtors, the return value references nothing from these objects that isn't in scope anymore. If it did then this would be an error even in C++, so don't worry about that
a_dtor(&aa);
a_dtor(&a);
return temp.mTest;
}
C++ "generated" code will not call dtors "after" the return statement. Dtors are called just like any other function.
Assume the C++ code is:
class A
{
public:
A(const A&) = delete;
A& operator = (const A&) = delete;
A()
{
std::cout << "A ctor" << std::endl;
mExampleBuffer = new char[128]; // allocate resources example, we don't do anything with this..
}
~A()
{
std::cout << "A dtor" << std::endl;
delete[] mExampleBuffer;
}
private:
char* mExampleBuffer = nullptr; // in real code this would be a std::vector or std::unique_ptr
};
Then used as:
void foo()
{
A a;
return; // not required, but here for clarity
}
Then in C this would be:
struct A
{
// there is no "private" in C, so we need people to read this comment and not mess with mExampleBuffer
char* mExampleBuffer;
};
void a_ctor(A* thisPtr)
{
printf("A ctor\n");
thisPtr->mExampleBuffer = malloc(sizeof(char)*128);
if (!thisPtr->mExampleBuffer)
{
// TODO: In C++ this would throw, in C you're gonna have to use setlongjmp or some such to simulate it.. plus use some sort of "cleanupstack" to do the unwinding
}
}
void a_dtor(A* thisPtr)
{
printf("A dtor\n");
free(thisPtr->mExampleBuffer);
}
void foo()
{
A a = {};
a_ctor(&a);
a_dtor(&a); // nothing magic here, simply called before the return statement
return;
}
As you can see for lots of classes using "real" C++ with RAII this would become a complete nightmare.. also you're not taking into account that the actual generated code would probably inline this so that there is no "class", i.e it would look something like:
void foo()
{
printf("A ctor\n");
char* mExampleBuffer = malloc(sizeof(char)*128); // not sure if would remove this or not since not used :) didn't check
printf("A dtor\n");
free(mExampleBuffer);
return;
}
Hopefully this explains the dtor mechanism. Don't forget that with inheritance each dtor must call the base.
I'd like to illustrate a way to return complex object in C by mimicking move semantics to expand on Peter G. answer.
struct T {
char * data;
};
void swap(T * a, T * b) {
swap(&a.data, &b.data);
}
void destruct(T & d) {
free(d.data);
}
void foo(T * rv) {
T x = {"Valueable data"};
swap(rv, &x); //This is what return in C++ does
destruct(&x); //This happens, when function scope in C++ ends
}
void bar() {
T holder = {0};
foo(holder);
destruct(&holder);
}
Notice how allocation and deallocation of an object are always in the same scope.
In C++, a value returned from a function must not refer to memory of local objects, that would be an error. So, to me it looks like you're possibly trying to solve a problem not even a C++ compiler has to solve.
If on the other you want simply want to return a value computed by one of the local objects, first assign the value computed by the object to a local variable, destruct the object and then return the pre-computed return value.

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++;
}
}

Resources