Call once,return twice

C

Cong Wang

Hi,all!
I found an interesting problem,it is that how to implement a C
function which can be called once and return twice? Just like the POSIX
function fork() or the library function longjmp().Only via using asm?
It is strange that I have searched the google groups and FAQs of this
group and "googled" the internet but find none useful info.
Thanks for any reply!
 
U

Ulrich Eckhardt

Cong said:
I found an interesting problem,it is that how to implement a C
function which can be called once and return twice? Just like the POSIX
function fork() or the library function longjmp().

The structure of C (and for that matter all stack based languages) is so
that you can add (a new function call context or local var) on top of the
stack or remove (return to old function call context or remove local var)
from the top of it. IOW, you need to break out this schema to achieve what
setjmp/longjmp or fork do - since your process' memory space is yours to
access in any way, there is nothing that should keep you from doing it.
Only via using asm?

No, you can do so via normal C code, but it requires knowledge of the
implementation, so the code you produce will be highly platform dependent.
Maybe you will need a few assembler macros eventually to set the
stackpointer or similar things that would be hard to achieve without.

Uli
 
W

Walter Roberson

The structure of C (and for that matter all stack based languages) is so
that you can add (a new function call context or local var) on top of the
stack or remove (return to old function call context or remove local var)
from the top of it. IOW, you need to break out this schema to achieve what
setjmp/longjmp or fork do - since your process' memory space is yours to
access in any way, there is nothing that should keep you from doing it.

No.

The call stack need not be accessible through normal operations.

There are processors in which the call stack is usually held
in-processor, and only "spilled" to memory when the register list
gets full.

There are processors in which the current return address is held
in a register, not on the stack, so memory manipulation cannot
change that return address [but might be able to change a previous
return address.]

There are processors in which the call stack is seperate
from the argument stack, and the call stack is held in a different
memory segment which is marked as not being writable -- processors
designed to twart buffer-overflow attacks.

Whether "your process' memory space is yours to
access in any way" depends on the architecture and implementation.
C promises only that your declared variables and malloc/alloc'd memory
are visible, and makes no promises about what might happen in
system calls, or library functions; it also makes no promises
about how function calls or argument passing are implemented.
 
M

Michael Wojcik

What you found is a bogus problem. There is no way to do what you
describe in standard C. There may be implementation-dependent ways
to do it for some implementations, but those are off-topic for
comp.lang.c.

Neither of those functions does what you describe.

It is illegal to pass longjmp a jmp_buf that was initialized with a
call to setjmp in a function that has since returned; it produces
undefined behavior. C90 7.6.2.1.

setjmp, which you did not cite, *appears* to (be able to) "return"
multiple times to the "caller". How this is actually implemented is
an implementation detail, and setjmp need not be implemented with an
actual function that actually returns. (setjmp itself must be a
macro. C90 7.6.1.1.)

<OT>The POSIX fork function does not return twice; nor does it cause
any other function to return twice. Describing it as "returning
twice" is misleading shorthand for what it actually does: create a
second process that is initially nearly identical to the calling
process. Each of those processes will return from fork, but in the
context of any one process fork only returns once. And, of course,
the manner in which fork achieves this is entirely implementation-
dependent and has nothing to do with portable C. said:
The structure of C (and for that matter all stack based languages) is so
that you can add (a new function call context or local var) on top of the
stack or remove (return to old function call context or remove local var)
from the top of it.

While a conforming C implementation must behave in a manner consis-
tent with a stack-based calling sequence, it is not required to use
an actual stack to implement it (modulo very generous definitions of
"stack"), and it is not required to keep automatic variables with
function call contexts.
IOW, you need to break out this schema to achieve what
setjmp/longjmp or fork do - since your process' memory space is yours to
access in any way,

This is not true for some conforming implementations.
there is nothing that should keep you from doing it.

Certainly there is. First, it is impossible in portable C. Second,
doing arbitrary things to "your process' memory space" (assuming such
a thing is well-defined in a given implementation) will almost
certainly produce undefined behavior. Third, there are implementa-
tions (eg C for the AS/400) which most definitely disallow it.

--
Michael Wojcik (e-mail address removed)

Memory, I realize, can be an unreliable thing; often it is heavily coloured
by the circumstances in which one remembers, and no doubt this applies to
certain of the recollections I have gathered here. -- Kazuo Ishiguro
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top