Why does a tail recursive function lead to a segmentation fault? [duplicate] - c

Given the C program with infinite recursion:
int main() {
main();
return 0;
}
Why would this result in a stack overflow. I know this results in undefined behaviour in C++ from the following thread Is this infinite recursion UB? (and as side node one can't call main() in C++). However, valgrind tells me this leads to a stack overflow:
Stack overflow in thread 1: can't grow stack to 0x7fe801ff8
and then finally the program ends due to a segmentation error:
==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907== Access not within mapped region at address 0x7FE801FF0
Is this also undefined behavior in C, or should this really lead to a stack overflow and then why does this result in a stack overflow?
edit
1 I would like to know is infinite recursion allowed in C?
2 Should this result in a stack overflow? (has been sufficiently answered)

Whenever you call a function, the arguments are pushed on the stack, which means that data on the stack segment is "allocated". When the function is called, the return adress is also pushed on the stack, by the CPU, so it knows where to return to.
In your example case this means, that no arguments are used, so the only thing that is pushed is the return adress, which is rather small (4 bytes on x86-32 architexture), and additionally the stackframe is adjusted which takes another four bytes on this architecture.
From this is follows that, once the stack segment is exhausted, the function can not be called aynmore and an exception is raised to the OS. Now there can happen two things. Either the OS forwards the exception back to your application which you will see as stack overflow. Or the OS can try to allocate additional space for the stack segemnt, up to a defined limit, after which the application will see the stack overflow.
So this code (I renamed it to infinite_recursion() as main() can not be called) ...
int inifinite_recursion(void)
{
inifinite_recursion();
return 0;
}
... looks like this:
_inifinite_recursion:
push ebp ; 4 bytes on the stack
mov ebp, esp
call _inifinite_recursion ; another 4 bytes on the stack
mov eax, 0 ; this will never be executed.
pop ebp
ret
UPDATE
Regarding the standard C99 for defining recursion, the best I found so far is in Section 6.5.2.2 Paragraph 11:
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
Of course this doesn't answer whether it is defined what happens when the stack overflows. However at least it allows main to be called recursively, while this is explicitly forbidden in C++ (Section 3.6.1 Paragraph 3 and Section 5.2.2 Paragraph 9).

Whether a program recurses infinitely is not decidable. No sensible standard will ever require a property that may be impossible to verify even for conforming programs, so no C standard, current or future, will ever have anything to say about infinite recursion (just as no C standard will ever require conforming programs to eventually halt).

Recursion is a type of iteration that implicitly preserves local state before moving to the next iteration. It is easy enough to reason this through by thinking of just regular functions calling each other, one after the other:
void iteration_2 (int x) {
/* ... */
}
void iteration_1 (int x) {
if (x > 0) return;
iteration_2(x + 1);
}
void iteration_0 (int x) {
if (x > 0) return;
iteration_1(x + 1);
}
Each iteration_#() is basically identical to each other, but each one has it's own x, and each one remembers which function had called it, so it can properly return back to the caller when the function it calls is done. This notion doesn't change when the program is converted into a recursive version:
void iteration (int x) {
if (x > 0) return;
iteration(x + 1);
}
The iteration becomes infinite if the stopping condition (the if check to return from the function) is removed. There is no returning from the recursion. So the information that is remembered for each successive function call (the local x and the address of the caller) keeps piling on until the OS runs out of memory to store that information.
It is possible to implement an infinitely recursive function that does not overflow the "stack". At sufficient optimization levels, many compilers can apply an optimization to remove the memory needed to remember anything for a tail recursive call. For instance, consider the program:
int iteration () {
return iteration();
}
When compiled with gcc -O0, it becomes:
iteration:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0, %eax
call iteration
leave
ret
But, when compiled with gcc -O2, the recursive call is removed:
iteration:
.LFB2:
.p2align 4,,7
.L3:
jmp .L3
The result of this infinite recursion is a simple infinite loop, and there will be no overrun of the "stack". So, infinite recursion is allowed since infinite loops are allowed.
Your program, however, is not a candidate for tail call optimization, since the recursive call is not the last thing your function does. Your function still has a return statement that follows the recursive call. Since there is still code that needs to execute after the recursive call returns, the optimizer cannot remove the overhead of the recursive call. It must allow the call to return normally, so that the code after it may execute. So, your program will always pay the penalty of storing the return address of the calling code.
The standard does not speak to "infinite recursion" in any specific terms. I have collected together what I believe relevant to your question.
Calling a function recursively is permitted (C.11 §6.5.2.2 ¶11)
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
Recursive entry into a statement creates new instances of local variables (C.11 §6.2.4 ¶5,6,7)
An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration, as do some compound literals. ...
For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. ...
For such an object that does have a variable length array type, its lifetime extends from
the declaration of the object until execution of the program leaves the scope of the
declaration. If the scope is entered recursively, a new instance of the object is created
each time.
The standard talks about memory allocation failure in numerous places, but never in the context of an object with automatic storage duration. Anything not explicitly defined in the standard is undefined, so a program that fails to allocate an object with automatic storage duration has undefined behavior. This would apply equally between a program that just had a very long function call chain or too many recursive calls.

Whenever you make a function call (including main()), the function call "info" (e.g. arguments) is pushed on top of the stack. This info is popped off the stack when the function returns. But as you can see in your code, you make a recursive call to main before you return, so stack keeps on growing until it hits its limit and hence the segmentation error.
The size of the stack is often limited and decided before runtime (e.g. by your operating system).
This means that stack overflow is not limited to main(), but to any other recursive functions without a proper way to terminate its tree (i.e. base cases).

Addressing questions 1:
I would like to know is infinite recursion allowed in C?
This article Compilers and Termination Revisited by John Regehr is answer on whether the C standard allows infinite recursion or not and after combing through the standard it is not too surprising to me that conclusions is that it is ambiguous. The article main thrust is about infinite loops and whether it is supported by the standard of various languages(including C and C++) to have non-terminating executions. As far as I can tell the discussion applies to infinite recursion just as well, of course assuming we can avoid a stack overflow.
Unlike C++ which says in section 1.10 Multi-threaded executions and data races paragraph 24:
The implementation may assume that any thread will eventually do one of the
following:
— terminate,
[...]
Which seems to rule out infinite recursion in C++. The draft C99 standard says in section 6.5.2.2 Function calls paragraph 11:
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
which does not put any limits on recursion and says this in section 5.1.2.3 Program execution paragraph 5:
The least requirements on a conforming implementation are:
— At sequence points, volatile objects are stable in the sense that previous
accesses are complete and subsequent accesses have not yet occurred.
— At program termination, all data written into files shall be identical to the
result that execution of the program according to the abstract semantics would
have produced.
— The input and output dynamics of interactive devices shall take place as
specified in 7.19.3. The intent of these requirements is that unbuffered or
line-buffered output appear as soon as possible, to ensure that prompting
messages actually appear prior to a program waiting for input.
As the article says, the first condition should be straight forward to meet, the third condition according to the article does not really cover termination. So we are left with the second condition to deal with. According to the article it is ambiguous, the quote from the article is as follows:
If it is talking about termination of the program running on the abstract machine, then it is vacuously met because our program does not terminate. If it is talking about termination of the actual program generated by the compiler, then the C implementation is buggy because the data written into files (stdout is a file) differs from the data written by the abstract machine. (This reading is due to Hans Boehm; I had failed to tease this subtlety out of the standard.)
So there you have it: the compiler vendors are reading the standard one way, and others (like me) read it the other way. It’s pretty clear that the standard is flawed: it should, like C++ or Java, be unambiguous about whether this behavior is permitted.
Since it seems like there are two reasonable yet conflicting interpretations of the second condition the standard is deficient and should define explicitly whether this behavior is permitted.

Even if the function does not use stack space for local variables or argument passing, it still needs to store the return address and (possibly) the frame's base pointer (with gcc, this can be disabled via -fomit-frame-pointer).
On high enough optimization levels, the compiler might be able to re-write the recursion into a loop if the tail-call optimization in applicable, which would avoid the stack overflow.

The stack section of the main memory is not infinite, so if you call a function recursively an indefinite number of times, the stack will be filled of informations about each single function invocation. This lead to a Stack Overflow, when there's no more space to use for any other function invocation.

Its important to understand how the calling stack of functions in C looks like:

Is infinite recursion allowed in C? The simple answer is Yes. The compiler will allow you to call a function infinitely until you run out of stack space; it will not prevent you from doing this.
Is infinite recursion possible? No. As pointed out already, each call to a function requires a return address to be pushed on the program stack, along with any parameters the function requires to operate. Your program only has a limited stack size and once you use up your stack your application will fail.
Is fake infinite recursion possible? Yes. It is possible to design a function which calls itself 1000 times and then allows itself to exit from the 1000 function calls, so that the stack only has the original function call on the stack... and then repeat the whole process all over again in a infinite loop. I don't consider this real infinite recursion though.

Infinite recursion is allowed in C. At compile time, the compiler will allow this, but you may get a runtime error upon doing so.

It's allowed in c, since the standard says ->
Recursive function calls shall be permitted, both directly and indirectly through any chain
of other functions.
In 6.5.2.2 -> 11
and the Stackoverflow happens simply, because each state of the calling scope, has to get stored, so if infinite states of scope have to be stored, your anywhen running out of memory, as you don't have infinite memory space. And this is defined behavior, because it is happening on runtime, and the compiler doesn't need to check in respect of the standard, if the recursion ever gets broken.

Cause stack is limited and whenever you call a function it saves the callee (by pushing base pointer onto stack and copying current stack pointer as new base pointer value) therefore consumes stack will overflow with infinite number of calls. See the calling convention and how stack reacts at here (http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml)

I just looked at copy a recent draft c standards doc and none of the recursion references talk about infinite recursion.
If the standard document doesn't require the compiler to support something and doesn't ban it, then compiler developers will consider this undefined behavior.

#include<iostream>
using namespace std;
int a();
int b();
int a()
{
cout<<"Hello World\n";
b();
return 0;
}
int b()
{
cout<<"Hello World\n";
a();
return 0;
}
void print(int b)
{
cout << b << endl;
}
int main()
{
int b = a();
print(b);
return 0;
}
This code returns this output in DevC++:
Process exited after 14.04 seconds with return value 3221225725
You can check here for what' the meaning of this value Dev C++ Process exited with return value 3221225725
So function calls in C++ binding every function in call stack . Also you know, this is limited size, every fuction call raise this size.

==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907== Access not within mapped region at address 0x7FE801FF0
What this means is the stack has grown so much due to the recursive calls and increments of rsp that it is has accessed a memory address outside of the virtual memory that the process mapped for the thread stack. The page fault handler will notice that the process hasn't allocated this region of virtual memory and will propagate the exception to the program by calling kernel exception and stack unwinding procedures. On windows, the top level SEH handler will then be invoked from the kernel32.dll .pdata section which will call an UnhandledExceptionFilter which can be set from application code using SetUnhandledExceptionFilter. This routine specified by the application can call GetExceptionCode to switch the exception constant and display relevant modal error dialog boxes.

Related

How stack structure works with compound statements inside a function?

I'm trying to learn c programming and can't understand how stacks work.
Everywhere I read I find that when a function is called stack frame is created in the stack which contains all the data for the function call- parameters, return address and local variables. And the stack frame is removed releasing the memory when the function returns.
But what if we had a compound statement inside the function which have its own variables. Is the memory for the local variables for block is also allocated inside the stack frame when the function call and released when it returns.
Example
int main(){
int a = 10;
if(int a<50){
int b=9;
}
else{
int c=10;
}
}
Is the memory for b and c is allocated with a when the function starts executing?
And deallocated when the function returns?
If so than there is no difference other than the visibility of the variable when declaring it in the beginning of the function or inside a another block in the function.
Please explain.
The C standard doesn't specify how such things are to be implemented. The C standard doesn't even mention a stack! A stack is a common way of implementing function calls but nothing in the standard requires a stack. All such things are implementation specific details. For the posted code, the standard only specifies when the variables are in scope.
So there is no general answer to your question. The answer depends on your specific system, i.e. processor, compiler, etc.
Provided that your system uses a stack (which is likely), the compiler may reserve stack space for all 3 variables or it may reserve space for 2 variables, i.e. one for awhile b and c share the other. Both implementations will be legal. The compiler is even allowed to place the variables directly in some registers so that nothing needs to be reserved on the stack.
You can check your specific system by looking at the generated assembly code.
A C implementation may implement this in multiple ways. Let’s suppose your example objects, a, b, and c, are actually used in your code in some way that results in the compiler actually allocating memory for them and not optimizing them away. Then:
The compiler could allocate stack space (by decreasing the top-of-stack pointer) for all of a, b, and c when the function starts, and release it when the function ends.
The compiler could allocate stack space for a when the function starts, then allocate space (again by decreasing the stack pointer) in the middle of the function when space for b or c is needed, then release that stack space as each block ends.
In a good modern compiler, the compiler is likely to analyze all the active lifetimes of the objects and find a somewhat optimal solution for using stack space in overlapping ways. By “active lifetime”, I mean the time from when the value of an object is set to the last time that value is needed (not the C standard’s definition of “lifetime”). For example, in int a = f(x); … g(a); h(y); a = f(y); … g(a);, there are actually two lifetimes for a, from its initial assignment to the first g(a) and from the assignment a = f(y); to the second g(a);. If the compiler needs memory to store a, it might use different memory for these two lifetimes.
Because of the above, what memory is used for which C object can get quite complicated. A particular memory location might be used for a at one time and for b at another. It may depend on loops and goto statements in your code. It also depends on whether the address of an object is taken—if the address is taken, the compiler may have to keep the object in one place, so that the address is consistent. (It might be able to get away without doing that, depending on how it can see the address is used.)
Basically, the compiler is free to use the stack, other memory, and registers in whatever way it chooses as long as the observable behavior of your program remains as it is defined by the C standard.
(The observable behavior is the input/output interactions of your program, the data written to files, and the accesses to volatile objects.)
Your example as stated is not valid since you have no brackets in the if-else statement. However, in the example below all variables are typically allocated when the function is entered:
int main(void)
{
int a = 10;
if (a < 50) {
int b = 9;
} else {
int c = 10;
}
}
As mentioned by user "500 - Internal Server Error", this is an implementation issue.

GCC - modify where execution continues after function return [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Is it possible to do something like this in GCC?
void foo() {
if (something()) returnSomewhereElse;
else return;
}
void bar() {
foo();
return; // something failed, no point of continuing
somewhereElse:
// execution resumes here if something succeeds
// ...
}
can this be achieved in a portable way, using C and GCC extensions, without using platform specific assembly?
the stack state will not change between the normal and altered return points, so is it possible to reuse the code that restores the stack and registers state from the regular return?
considering that the function may or may not be inlined, if called it must alter the return address, if inlined it must only alter the code path but not the current function return address, as that would break the code
the alternate return point does not need to be a label, but I am hoping GCC's address of label extension can come in handy in this situation
Just to clarify the intent - it is about error handling. This example is a minimal one, just to illustrate things. I intend to use that in a much deeper context, to stop execution if an error occurs. I also assume the state doesn't change, which I may be wrong about, because there are no extra local variables added between the two return points, so I was hoping the code generated by the compiler to do that on foo's return can be reused for that and save the overhead of using longjmp, setting and passing the jump buffers.
The example "does make sense" because its intent is to show what I want to achieve, not why and how it would make sense in actual code.
Why is your idea simpler of better then simply returning a value from
foo() and having bar() either return or execute somewhereElse:
conditionally?
It is not simpler, and what you suggest is not applicable in practice, only in the context of a trivial example, but it is better because:
1 - it doesn't involve an additional returning of a value
2 - it doesn't involve an additional checking of a value
3 - it doesn't involve an additional jump
I am probably incorrectly assuming the goal should be clear at this point, and after all the clarifications and explanations. The idea is to provide an "escape code path" from a deep call chain without any additional overhead. By reusing the code the compiler has generated to restore the state of the previous call frame and simply modify the instruction at which execution resumes after the function returns. Success skips the "escape code path", the first error that occurs enters it.
if (failure) return; // right into the escape code path
else {
doMagickHere(); // to skip the escape code path
return; // skip over the escape code path
}
//...
void bar() {
some locals;
foo();
// enter escape code path here on foo failure so
destroy(&locals); // cleanup
return; // and we are done
skipEscapeCodePath: // resume on foo success
// escape path was skipped so locals are still valid
}
As for the claims made by Basile Starynkevitch that longjmp is "efficient" and that "Even a billion longjmp remains reasonable" - sizeof(jmp_buf) gives me a hefty 156 bytes, which is apparently the space needed to save pretty much all registers and a bunch of other stuff, so it can later be restored. Those are a lot of operations, and doing that a billion times is far, far outside of my personal understandings of "efficient" and "reasonable". I mean a billion jump buffers themselves are over 145 GIGABYTES of memory alone, and then there is the CPU time overhead as well. Not a whole lot of systems out there which can even afford that kind of "reasonable".
No, this is not possible portably, and I'm not sure to guess exactly what you want to achieve.
Terminology
Perhaps you want some non-local jump. Read carefully about setjmp.h, coroutines, call stack, exception handling, continuations, and continuation-passing-style. Understanding what call/cc is in Scheme should be very beneficial.
setjmp and longjmp
setjmp and longjmp are standard C99 functions (and they are quite fast, because the saved state is actually quite small). Be quite careful when you use them (in particular to avoid any memory leak). longjmp (or the related siglongjmp in POSIX) is the only way in portable standard C99 to escape from some function and get back into some caller.
The idea is to provide an "escape code path" from a deep call chain without any additional overhead
This is exactly the role of longjmp with setjmp. Both are quick, constant-time, operations (in particular unwinding a call stack of many thousands of call frames with longjmp takes a short and constant time). The memory overhead is practically one local jmp_buf per catch point, not a big deal. The jmp_buf is rarely put outside of the call stack.
A common way to use efficiently them would be to put the setjmp-ed jmp_buf in a local struct (so in your call frame) and pass the pointer to that struct to some internal static function(s) which indirectly would call longjmp on error. Hence setjmp and longjmp can, with wise coding conventions, mimic quite well and efficiently the complex semantics of C++ exception throwing and handling (or of Ocaml exceptions, or of Java exceptions, which both have a different semantics than C++). They are portable basic bricks enough for such a purpose.
Practically speaking, code something like:
struct my_foo_state_st {
jmp_buf jb;
char* rs;
// some other state, e.g a ̀ FILE*` or whatever
};
/// returns a `malloc̀ -ed error message on error, and NULL on success
extern const char* my_foo (struct some_arg_st* arg);
The struct my_foo_state_st is the private state. The my_foo is the public function (which you would declare in some public header). You did document (at least in the comment) that it returns a heap allocated error message on failure, hence the caller is responsible for freeing it. On success, you documented that it returns NULL. Of course, you could have other conventions and other arguments and/or result.
We declare and implement now an error function which is printing the error message into the state and escapes with a longjmp
static void internal_error_printf (struct my_foo_state*sta,
int errcode,
const char *fmt, ...)
__attribute__((noreturn, format(printf(2,3))));
void internal_error_printf(struct my_foo_state*sta,
int errcode, const char *fmt, ...) {
va_arg args;
va_start(args, fmt);
vasprintf(&sta->rs, fmt, args);
va_end(args);
longjmp(sta->jb, errcode);
}
We now have several possibly complex and recursive functions doing the bulk of the work. I only sketch them, you know what you want them to do. Of course you might want to give them some additional arguments (that is often useful, and it is up to you).
static void my_internal_foo1(struct my_foo_state_st*sta) {
int x, y;
// do something complex before that and compute x,y
if (SomeErrorConditionAbout(sta))
internal_error_printf(sta, 35 /*error code*/,
"errror: bad x=%d y=%d", x, y);
// otherwise do something complex after that, and mutate sta
}
static void my_internal_foo2(struct my_foo_state_st*sta) {
// do something complex
if (SomeConditionAbout(sta))
my_internal_foo1(sta);
// do something complex and/or mutate or use `sta`
}
(even if you have dozens of internal functions like above, you don't consume a jmp_buf in any of them; and you could also recurse quite deeply in them. You just need to pass a pointer -to struct my_foo_state_st in all of them, and if you are single-threaded and don't care about reentrancy, you could store that pointer in some static variable... or some thread-local one, without even passing it in some argument, which I find still preferable -since more re-entrant and thread friendly).
At last, here is the public function: it sets up the state and do a setjmp
// the public function
const char* my_foo (struct some_arg_st* arg) {
struct my_state_st sta;
memset(&sta, 0, sizeof(sta));
int err = setjmp(sta->jb);
if (!err) { // first call
/// put something in `sta` related to ̀ arg̀
/// start the internal processing
//// later,
my_internal_foo1(&sta);
/// and other internal functions, possibly recursive ones
/// we return NULL to tell the caller that all is ok
return NULL;
}
else { // error recovery
/// possibly release internal consumed resources
return sta->rs;
};
abort(); // this should never be reached
}
Notice that you can call your my_foo a billion times, it will not consume any heap memory when not failing, and the stack will grow by a hundred of bytes (released before returning from my_foo). And even if it failed a billion times by your private code calling a billion times the internal_error_printf no memory leak happens (because you documented that my_foo is returning an error string which the caller should free) if coding properly.
Hence using properly setjmp and longjmp a billion times does not eat a lot of memory (only a few hundred bytes on the call stack for one single local jmp_buf, which is popped on the my_foo function return). Indeed, longjmp is slightly more costly than a plain return (but it does the escape that return does not), so you would prefer to use it on error situations.
But using setjmp and longjmp is tricky but efficient and portable, and makes your code difficult to understand as documented by setjmp. It is important to comment it quite seriously. Using these setjmp and longjmp cleverly and wisely does not require "gigabytes" of RAM, as wrongly said in the edited question (because you consume only one single jmp_buf on the call stack, not billions of them). If you want more sophisticated control flow, you'll use a local jmp_buf at each and every dynamic "catch point" in the call stack (and you'll probably have a dozens of them, not billions). You'll need millions of jmp_buf only in the hypothetical case of a recursion of several millions call frames, each being a catch point, and that is not realistic (you'll never have a recursion of a depth of one million, even without any exception handling).
See this for a better explanation of setjmp for "exception" handling in C (and SFTW for other ones). FWIW, Chicken Scheme has a very inventive usage of longjmp and setjmp (related to garbage collection and to call/cc !)
Alternatives
setcontext(3) was perhaps POSIX but is now obsolete.
GCC has several useful extensions (some of them understood by Clang/LLVM) : statement exprs, local labels, labels as values and computed goto, nested functions, constructing function calls, etc.
(My feeling is that you are misunderstanding some concepts, notably the precise role of the call stack, so your question is very unclear; I gave some useful references)
returning a small struct
Notice also that on some ABIs, notably x86-64 ABI on Linux, returning a small struct (e.g. of two pointers, or of one pointer and one int or long or intptr_t number) is extremely efficient (since both pointers or integers go thru registers), and you could take advantage of that: decide that your function returns a pointer to the primary result and some error code, both packed in a single small struct:
struct tworesult_st {
void* ptr;
int err;
};
struct towresult_st myfunction (int foo) {
void* res = NULL;
int errcode = 0;
/// do something
if (errcode)
return (struct tworesult_st){NULL, errcode};
else
return (struct tworesult_st){res, 0};
}
On Linux/x86-64 the code above is optimized (when compiled with gcc -Wall -O) to return in two registers (without any stack consumed for the returned struct).
Using such a function is simple and very efficient (no memory involved, the two member ̀ struct` will be passed in processor registers) and could be as simple as:
struct tworesult_st r = myfunction(34);
if (r.err)
{ fprintf(stderr, "myfunction failed %d\n", r.err); exit(EXIT_FAILURE); }
else return r.ptr;
Of course you could have some better error handling (it is up to you).
Other hints
Read much more about semantics, in particular operational semantics.
If portability is not the major concern, study the calling conventions of your system and its ABI and the generated assembler code (gcc -O -Wall -fverbose-asm foo.c then look inside foo.s) , and code the relevant asm instructions.
Perhaps libffi could be relevant (but I still don't understand your goals, only guessed them).
You could try using label exprs and computed gotos, but unless you understand the generated assembler code, the result might not be what you expect (because the stack pointer changes at function calls and returns).
Self-modifying code is frowned upon (and "impossible" in standard C99), and most C implementations put the binary code in a read-only code segment. Read also about trampoline functions. Consider perhaps JIT compiling techniques, à la libjit, asmjit, GCCJIT.
(I firmly believe that the pragmatical answer to your concerns is either longjmp with suitable coding conventions, or simply returning a small struct; both can be used portably in a very efficient way, and I cannot imagine a case where they are not efficient enough)
Some languages: Scheme with its call/cc, Prolog with its backtracking features, are perhaps more adapted (than C99 is) to the needs of the OP.
After giving it some extra thought, it is not as simple as it initially appeared. There is one thing that prevents it from working - the code of functions is not context aware - there is no way of knowing the frame it was invoked in, and that has two implications:
1 - modifying the instruction pointer if not portable is easy enough, as every implementation defines a consistent place for it, it is usually the first thing on the stack, however modifying its value to skip the escape trap will also skip the code which restores the previous frame state, since that code is there, not in the current frame - it can't perform state restoration since it has no information of it, the remedy for that, if an extra check and jump are to be omitted is to duplicate the state restoring code in both locations, unfortunately, this can only be done in assembly
2 - the amount of instructions which need to be skipped is unknown too, and depends on which is the previous stack frame, depending on the number of locals that need destruction it will vary, it will not be a uniform value, the remedy for that would be to push both the error and success instruction pointers on the stack when the function is invoked, so it can restore one or the other depending on whether an error occurs or not. Unfortunately, that too can only be done in assembly.
Seems that such a scheme can only be implemented on level compiler, demanding its own calling convention, which pushes two return locations and inserts state restoration code at both. And the potential savings from this approach hardly merit the effort to write a compiler.

Does C destroy return variable before the closing brace?

Somebody told me that in C (and C++) that the variable present in a return statement is destroyed before closing brace of the function.
Ex -
int func() {
int a = 10;
return a; // I was told that a is destroyed here
}
Does it really happen that way? If yes, how does the function return value to the calling function?
My intuition tells me that the variable value is pushed on to stack at the return value and when it goes back to the calling function, the stack top is popped there by getting the return value. Not sure if I'm correct.
Does C destroy return variable before the closing brace?
Yes ... sort of.
Local variables go out of scope at the end of a method, and after that, they cease to be accessible.
In C, that simply means that the storage for the variable itself becomes available for other uses. But there is no active "destruction" of the variable.
In C++, the variable's destructor (if there is one) will be invoked when the variable goes out of scope.
At an implementation level, the storage space for local variables is typically managed using a stack. But I don't think this is mandated by the respective language specifications.
It is also important to note that we are talking about variables, not values. In your example, the value of the variable is going to be returned to the caller (vide the return statement) and will continue to exist beyond the } ...
how does the function return value to the calling function?
Your intuition is right (partially). In some architecture the value is stored at stack and get popped when returning to the caller. But keep in mind that a value is returned from a function, not the variable itself.
C: How to Program: Ch-5: C Functions:
When a program calls a function, the called function must know how to return to its
caller, so the return address of the calling function is pushed onto the program execution stack (sometimes referred to as the function call stack).
The program execution stack also contains the memory for the local variables used in
each invocation of a function during a program’s execution. This data, stored as a portion of the program execution stack, is known as the activation record or stack frame of the function call. When a function call is made, the activation record for that function call is pushed onto the program execution stack. When the function returns to its caller, the activation record for this function call is popped off the stack and those local variables are no longer known to the program.
EDIT: As others mentioned is comments that this is implementation specific I changed my mind.
For x86 wiki says:
Calling conventions describe the interface of called code:
1. The order in which atomic (scalar) parameters, or individual parts of a complex parameter, are allocated
2. How parameters are passed (pushed on the stack, placed in registers, or a mix of both)
3. Which registers the callee must preserve for the caller
4. How the task of preparing the stack for, and restoring after, a function call is divided between the caller and the callee
There are often subtle differences in how various compilers implement these conventions.

Infinite recursion in C

Given the C program with infinite recursion:
int main() {
main();
return 0;
}
Why would this result in a stack overflow. I know this results in undefined behaviour in C++ from the following thread Is this infinite recursion UB? (and as side node one can't call main() in C++). However, valgrind tells me this leads to a stack overflow:
Stack overflow in thread 1: can't grow stack to 0x7fe801ff8
and then finally the program ends due to a segmentation error:
==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907== Access not within mapped region at address 0x7FE801FF0
Is this also undefined behavior in C, or should this really lead to a stack overflow and then why does this result in a stack overflow?
edit
1 I would like to know is infinite recursion allowed in C?
2 Should this result in a stack overflow? (has been sufficiently answered)
Whenever you call a function, the arguments are pushed on the stack, which means that data on the stack segment is "allocated". When the function is called, the return adress is also pushed on the stack, by the CPU, so it knows where to return to.
In your example case this means, that no arguments are used, so the only thing that is pushed is the return adress, which is rather small (4 bytes on x86-32 architexture), and additionally the stackframe is adjusted which takes another four bytes on this architecture.
From this is follows that, once the stack segment is exhausted, the function can not be called aynmore and an exception is raised to the OS. Now there can happen two things. Either the OS forwards the exception back to your application which you will see as stack overflow. Or the OS can try to allocate additional space for the stack segemnt, up to a defined limit, after which the application will see the stack overflow.
So this code (I renamed it to infinite_recursion() as main() can not be called) ...
int inifinite_recursion(void)
{
inifinite_recursion();
return 0;
}
... looks like this:
_inifinite_recursion:
push ebp ; 4 bytes on the stack
mov ebp, esp
call _inifinite_recursion ; another 4 bytes on the stack
mov eax, 0 ; this will never be executed.
pop ebp
ret
UPDATE
Regarding the standard C99 for defining recursion, the best I found so far is in Section 6.5.2.2 Paragraph 11:
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
Of course this doesn't answer whether it is defined what happens when the stack overflows. However at least it allows main to be called recursively, while this is explicitly forbidden in C++ (Section 3.6.1 Paragraph 3 and Section 5.2.2 Paragraph 9).
Whether a program recurses infinitely is not decidable. No sensible standard will ever require a property that may be impossible to verify even for conforming programs, so no C standard, current or future, will ever have anything to say about infinite recursion (just as no C standard will ever require conforming programs to eventually halt).
Recursion is a type of iteration that implicitly preserves local state before moving to the next iteration. It is easy enough to reason this through by thinking of just regular functions calling each other, one after the other:
void iteration_2 (int x) {
/* ... */
}
void iteration_1 (int x) {
if (x > 0) return;
iteration_2(x + 1);
}
void iteration_0 (int x) {
if (x > 0) return;
iteration_1(x + 1);
}
Each iteration_#() is basically identical to each other, but each one has it's own x, and each one remembers which function had called it, so it can properly return back to the caller when the function it calls is done. This notion doesn't change when the program is converted into a recursive version:
void iteration (int x) {
if (x > 0) return;
iteration(x + 1);
}
The iteration becomes infinite if the stopping condition (the if check to return from the function) is removed. There is no returning from the recursion. So the information that is remembered for each successive function call (the local x and the address of the caller) keeps piling on until the OS runs out of memory to store that information.
It is possible to implement an infinitely recursive function that does not overflow the "stack". At sufficient optimization levels, many compilers can apply an optimization to remove the memory needed to remember anything for a tail recursive call. For instance, consider the program:
int iteration () {
return iteration();
}
When compiled with gcc -O0, it becomes:
iteration:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0, %eax
call iteration
leave
ret
But, when compiled with gcc -O2, the recursive call is removed:
iteration:
.LFB2:
.p2align 4,,7
.L3:
jmp .L3
The result of this infinite recursion is a simple infinite loop, and there will be no overrun of the "stack". So, infinite recursion is allowed since infinite loops are allowed.
Your program, however, is not a candidate for tail call optimization, since the recursive call is not the last thing your function does. Your function still has a return statement that follows the recursive call. Since there is still code that needs to execute after the recursive call returns, the optimizer cannot remove the overhead of the recursive call. It must allow the call to return normally, so that the code after it may execute. So, your program will always pay the penalty of storing the return address of the calling code.
The standard does not speak to "infinite recursion" in any specific terms. I have collected together what I believe relevant to your question.
Calling a function recursively is permitted (C.11 §6.5.2.2 ¶11)
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
Recursive entry into a statement creates new instances of local variables (C.11 §6.2.4 ¶5,6,7)
An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration, as do some compound literals. ...
For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. ...
For such an object that does have a variable length array type, its lifetime extends from
the declaration of the object until execution of the program leaves the scope of the
declaration. If the scope is entered recursively, a new instance of the object is created
each time.
The standard talks about memory allocation failure in numerous places, but never in the context of an object with automatic storage duration. Anything not explicitly defined in the standard is undefined, so a program that fails to allocate an object with automatic storage duration has undefined behavior. This would apply equally between a program that just had a very long function call chain or too many recursive calls.
Whenever you make a function call (including main()), the function call "info" (e.g. arguments) is pushed on top of the stack. This info is popped off the stack when the function returns. But as you can see in your code, you make a recursive call to main before you return, so stack keeps on growing until it hits its limit and hence the segmentation error.
The size of the stack is often limited and decided before runtime (e.g. by your operating system).
This means that stack overflow is not limited to main(), but to any other recursive functions without a proper way to terminate its tree (i.e. base cases).
Addressing questions 1:
I would like to know is infinite recursion allowed in C?
This article Compilers and Termination Revisited by John Regehr is answer on whether the C standard allows infinite recursion or not and after combing through the standard it is not too surprising to me that conclusions is that it is ambiguous. The article main thrust is about infinite loops and whether it is supported by the standard of various languages(including C and C++) to have non-terminating executions. As far as I can tell the discussion applies to infinite recursion just as well, of course assuming we can avoid a stack overflow.
Unlike C++ which says in section 1.10 Multi-threaded executions and data races paragraph 24:
The implementation may assume that any thread will eventually do one of the
following:
— terminate,
[...]
Which seems to rule out infinite recursion in C++. The draft C99 standard says in section 6.5.2.2 Function calls paragraph 11:
Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.
which does not put any limits on recursion and says this in section 5.1.2.3 Program execution paragraph 5:
The least requirements on a conforming implementation are:
— At sequence points, volatile objects are stable in the sense that previous
accesses are complete and subsequent accesses have not yet occurred.
— At program termination, all data written into files shall be identical to the
result that execution of the program according to the abstract semantics would
have produced.
— The input and output dynamics of interactive devices shall take place as
specified in 7.19.3. The intent of these requirements is that unbuffered or
line-buffered output appear as soon as possible, to ensure that prompting
messages actually appear prior to a program waiting for input.
As the article says, the first condition should be straight forward to meet, the third condition according to the article does not really cover termination. So we are left with the second condition to deal with. According to the article it is ambiguous, the quote from the article is as follows:
If it is talking about termination of the program running on the abstract machine, then it is vacuously met because our program does not terminate. If it is talking about termination of the actual program generated by the compiler, then the C implementation is buggy because the data written into files (stdout is a file) differs from the data written by the abstract machine. (This reading is due to Hans Boehm; I had failed to tease this subtlety out of the standard.)
So there you have it: the compiler vendors are reading the standard one way, and others (like me) read it the other way. It’s pretty clear that the standard is flawed: it should, like C++ or Java, be unambiguous about whether this behavior is permitted.
Since it seems like there are two reasonable yet conflicting interpretations of the second condition the standard is deficient and should define explicitly whether this behavior is permitted.
Even if the function does not use stack space for local variables or argument passing, it still needs to store the return address and (possibly) the frame's base pointer (with gcc, this can be disabled via -fomit-frame-pointer).
On high enough optimization levels, the compiler might be able to re-write the recursion into a loop if the tail-call optimization in applicable, which would avoid the stack overflow.
The stack section of the main memory is not infinite, so if you call a function recursively an indefinite number of times, the stack will be filled of informations about each single function invocation. This lead to a Stack Overflow, when there's no more space to use for any other function invocation.
Its important to understand how the calling stack of functions in C looks like:
Is infinite recursion allowed in C? The simple answer is Yes. The compiler will allow you to call a function infinitely until you run out of stack space; it will not prevent you from doing this.
Is infinite recursion possible? No. As pointed out already, each call to a function requires a return address to be pushed on the program stack, along with any parameters the function requires to operate. Your program only has a limited stack size and once you use up your stack your application will fail.
Is fake infinite recursion possible? Yes. It is possible to design a function which calls itself 1000 times and then allows itself to exit from the 1000 function calls, so that the stack only has the original function call on the stack... and then repeat the whole process all over again in a infinite loop. I don't consider this real infinite recursion though.
Infinite recursion is allowed in C. At compile time, the compiler will allow this, but you may get a runtime error upon doing so.
It's allowed in c, since the standard says ->
Recursive function calls shall be permitted, both directly and indirectly through any chain
of other functions.
In 6.5.2.2 -> 11
and the Stackoverflow happens simply, because each state of the calling scope, has to get stored, so if infinite states of scope have to be stored, your anywhen running out of memory, as you don't have infinite memory space. And this is defined behavior, because it is happening on runtime, and the compiler doesn't need to check in respect of the standard, if the recursion ever gets broken.
Cause stack is limited and whenever you call a function it saves the callee (by pushing base pointer onto stack and copying current stack pointer as new base pointer value) therefore consumes stack will overflow with infinite number of calls. See the calling convention and how stack reacts at here (http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml)
I just looked at copy a recent draft c standards doc and none of the recursion references talk about infinite recursion.
If the standard document doesn't require the compiler to support something and doesn't ban it, then compiler developers will consider this undefined behavior.
#include<iostream>
using namespace std;
int a();
int b();
int a()
{
cout<<"Hello World\n";
b();
return 0;
}
int b()
{
cout<<"Hello World\n";
a();
return 0;
}
void print(int b)
{
cout << b << endl;
}
int main()
{
int b = a();
print(b);
return 0;
}
This code returns this output in DevC++:
Process exited after 14.04 seconds with return value 3221225725
You can check here for what' the meaning of this value Dev C++ Process exited with return value 3221225725
So function calls in C++ binding every function in call stack . Also you know, this is limited size, every fuction call raise this size.
==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907== Access not within mapped region at address 0x7FE801FF0
What this means is the stack has grown so much due to the recursive calls and increments of rsp that it is has accessed a memory address outside of the virtual memory that the process mapped for the thread stack. The page fault handler will notice that the process hasn't allocated this region of virtual memory and will propagate the exception to the program by calling kernel exception and stack unwinding procedures. On windows, the top level SEH handler will then be invoked from the kernel32.dll .pdata section which will call an UnhandledExceptionFilter which can be set from application code using SetUnhandledExceptionFilter. This routine specified by the application can call GetExceptionCode to switch the exception constant and display relevant modal error dialog boxes.

Infinite recursive calls should raise a stack overflow in this case?

I've recently thought about this case of stack overflow:
int f()
{
return f();
}
int main(void)
{
f();
return 0;
}
which definitely crashes the program. But my question is why is this not the same as an infinite loop? The compiler in the case of a recursive call at the return line could realize there's no need to keep any information of the calling function since the returning point to the called function is the same than that of the caller.
Now, in this case I agree the compiler needs to keep the information of the functions making the calls in the stack:
int f()
{
int x = f();
return x;
}
int main(void)
{
f();
return 0;
}
For sure I'm missing something, I'd appreciate if someone explains it to me. Regards
It turns out that in some compilers, with the right optimization flags, this actually won't cause a stack overflow! In fact, I tried compiling your program in g++. With optimization at defaults, it causes a stack overflow, but at optimization level -O3 it just goes into an infinite loop.
The reason that there's a difference between infinite recursion and infinite loops has to do with how the compiler, by default, implements these constructs. Loops historically have been implemented using branching instructions that tell the processor to pick up execution at a different part of the program. All these instructions do is jump the program counter someplace else, which just modifies the contents of a register. Function calls, on the other hand, are implemented by adding a new activation record to the stack to encode the arguments, return address, etc. so that when the function returns, it knows where to return to.
That said, this isn't "the way" that function calls or branches have to be implemented. You could, in theory, implement loops by using function calls and returns, though no compiler does so. Similarly, with functions that are tail-recursive (as is your example), compilers are often smart enough to elide all of the stack manipulations and to convert it to a naive branch instruction to avoid the overhead of stack setup and teardown.
In short, the reason you get different behavior is based on how the compiler decides to implement the code. If it's smart enough to see that it doesn't need to do an expensive function call setup, then it will convert the call into a simple loop instruction and loop forever. If it doesn't detect this, then it will fall back on the naive function call mechanism.
You aren't missing anything. Compile the program using gcc -O2 and there is no stack overflow.
It still needs to push the program counter on the stack each time a new function is called.
That is one of the reason why the stack grows at each function invocation.
My guess is that C compiler writers probably do not feel it highly necessary to optimize the output of infinitely recursive calls to empty functions...
C is not required to eliminate tail calls. (Scheme is required to perform TCO.)
I think that it really is a question of the compiler then and how optimized it is. I would imagine that in both cases, a while loop and this endlessly recursive call, the machine
instructions written are as explicitly as possible converting your wishes into instructions. As you know, for the while loop, the you are just jmp'ing back to the specific location and continuing from there. with the recursive call, you are pushing on a new value on the stack, so, per your question, I guess its really a question of how smart your compiler is ...

Resources