473,766 Members | 2,180 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

various exits from function with one general clean-up?

Hi,

when I need to execute a general clean-up procedure (inside of a
function) just before the function returns -- how do I do that when
there are several returns spread over the whole function?

My first approach: Use "while(1)" and "break", however this doesn't work
if there is another loop inside (since I can't break two loops at the
same time):

void f(){
while(1){

if ...

break; /* first return: */

switch(...){
case ...:

break; /* second return (doesn't work): */
}

/* other code */

break; /* break in any case */
}
/* clean up procedure */
}
Could someone solve this -- or maybe provide a better solution in
general?

Thanks
Felix
Nov 14 '05 #1
7 2245

"Felix Kater" <f.******@gmx.n et> wrote in message
news:20******** *************@c omppasch.pi4.la n...
Hi,

when I need to execute a general clean-up procedure (inside of a
function) just before the function returns -- how do I do that when
there are several returns spread over the whole function?
Then don't do that...
Could someone solve this -- or maybe provide a better solution in
general?
Hint A) Use a 'goto'. This is one of the *very* few occasions where I would
advice this.
Hint B) Keep a 'status' local var and check it for every step, return status
*once*.
Hint C) Abstract 'cleanup' into a specialized function. Call it when
appropriate.

Thanks
Felix

Nov 14 '05 #2
In article <20************ *********@compp asch.pi4.lan>,
Felix Kater <f.******@gmx.n et> wrote:
My first approach: Use "while(1)" and "break"


The result would be completely unreadable even if it worked. Use a
straightforward goto instead.

-- Richard
Nov 14 '05 #3
On Mon, 6 Dec 2004 16:26:04 +0100, Felix Kater
<f.******@gmx.n et> wrote:
when I need to execute a general clean-up procedure (inside of a
function) just before the function returns -- how do I do that when
there are several returns spread over the whole function?
I assume that you mean cleaning up mess local to the function, rather
than global mess (the latter is best done with another function called
on exit).
My first approach: Use "while(1)" and "break", however this doesn't work
if there is another loop inside (since I can't break two loops at the
same time):
No, it doesn't. "Labelled break" would be useful.
Could someone solve this -- or maybe provide a better solution in
general?


One way is to restructure the code so that there is only one exit, using
if/else etc. and storing the result for the exit. Another (which can be
combined) is to use status flags and/or state variables.

Or you can use goto, which is in many cases the cleanest solution
especially for error traps. If a function has one label at the bottom,
clearly marked and commented, and the only thing it does is cleanup and
exit, it can be easily understood and maintained (better than
duplicating code for each return or having a baroque system of flags).

Chris C
Nov 14 '05 #4
Chris Croughton wrote:
[...]
One way is to restructure the code so that there is only one exit, using
if/else etc. and storing the result for the exit. Another (which can be
combined) is to use status flags and/or state variables.


Another way to do the restructuring is to wrap the multi-
return function inside a caller that handles the resource
allocation and cleanup:

void f(void) {
char *string = malloc(...);
FILE *stream = fopen(...);
inner_f_with_mu ltiple_returns( string, stream);
fclose(stream);
free(string);
}

This requires that the "dirtying" can all be done before
the "real work," and that all the cleanup can be postponed
until afterward. However, that pattern describes quite a
few functions -- and those that it doesn't describe might
be candidates for decomposition anyhow.

--
Er*********@sun .com

Nov 14 '05 #5
On Mon, 06 Dec 2004 12:34:09 -0500, Eric Sosman
<er*********@su n.com> wrote:
Chris Croughton wrote:
[...]
One way is to restructure the code so that there is only one exit, using
if/else etc. and storing the result for the exit. Another (which can be
combined) is to use status flags and/or state variables.
Another way to do the restructuring is to wrap the multi-
return function inside a caller that handles the resource
allocation and cleanup:


Yes, if the resources are simple enough that's the way I do it. If it
involves passing more than a couple of extra parameters then I find it
messy (or if some of the allocation needs extra calculation first).
This requires that the "dirtying" can all be done before
the "real work," and that all the cleanup can be postponed
until afterward. However, that pattern describes quite a
few functions -- and those that it doesn't describe might
be candidates for decomposition anyhow.


As in the woman who asked "Is Beethoven still composing?" and got the
reply "No madam, he is decomposing!" <g>. I think some code should
definitely decomposed, or even composted...

Yes, most functions I've used which allocate and then free resources
have been able to be implemented using wrappers as you describe. A few
haven't, and some have been imossible to split up without making the
interfaces very odd and nonintuitive...

(Actually, I haven't used a goto in C for at least 10 years, I've always
been able to code round it. I've seen some code where it was the
"obviously correct" answer, though...)

Chris C
Nov 14 '05 #6
On Mon, 6 Dec 2004 15:26:04 UTC, Felix Kater <f.******@gmx.n et> wrote:
Hi,

when I need to execute a general clean-up procedure (inside of a
function) just before the function returns -- how do I do that when
there are several returns spread over the whole function?


There are different details:
- follow the roule that no fuction should be have more lines
of code than a screen (print) page can show.
This makes it easier to understund the code
and helps debugging the whole program
- if the function goes too big for the rule above you tries
to make too much details at once. Then break down the whole
job in multiple little functions (even as each function
gets called only one).
- define the style for each function:
- has only ONE return in case its job gets done well
but multiple returns on errors.
This will be the case when the awaited result is:
"done anything well"
- has only one return in case its job fails
but multiple returns its job is done well.
This will be the case when the natural result of that job
is: "something fails as expected"
- has only exactly ONE return point
This is the case when even something fails the total
work has to be done and either NO fail at all occurs
or even NO result is needed.
depending if you can identify WELL as ONE single value
or its easier to define ONE single value as error indicator.
- define the most significant value as return value and
less significant ones (when there are some)
as parameter.
The function result will be
- only an indicator of success/fail (like pointer/NULL pointer)
optionally another parameter gives more details about errors
- a pure error code
- one value indicates success (e.g. 0)
any other gives the error number
In both cases you needs on the calling point only one if
to differ between success and fail of this step
- Splitting out a whole switch statement
into a separate function using the roles above.
This helps you to differ WHAT from HOW.
- You may even have a need to split out each (or some)
case into own functions to separate out "WHAT is to do"
from "HOW is it done"
- in general:
when a function gets too big to follow the first role
it is easy too see that you have too much work for a
single function.
Spitting out "WHAT" from "HOW" is to do helps you
to get your mind clean. Define a function for each "What"
to hide details from the "WHAT".
If "HOW" is too much again split this detail again.
This method will allow you
- debug each detail alone by writing a debug main(),
compile little function alone, test it using different
testdata.
- debug outer functions using theyr input leaving out
inner functions during trace because you knows they
should work already.
- split up each function in at least 3 logical blocks
whereas each can be empty:
1. init
A check input parameters when needed
B allocate resources the fuction and its helper functions
needs - but only if A was successfull
a memory/files needed for internal work
b memory/files needed to return to caller
2. do the work only when 1. successfull
3. clean up
free all resources you have not return to the caller,
a close/remove files (only when they are created/opened
successfull).
Attention: the result from close() and rmove()
may change your result from success to fail!
b free memory (free() allows to be called with NULL
pointers! So you can blindly free() anything.
Each of 1-3, A+B, a+b can be done one or more helper fuctions.
if, if - else, if - else - if is a wounderful constunct - but
only if you gets your code so structured that they are NOT
got nested deep. Deep nesting points you to a design error.
Roll up the WHAT/HOW levels from scratch at this point.

At least your whole program will follow the rule:
I WHAT is to do.
Describes a (sub)job on what kind on work is to do
but lefts open HOW it gets done by calling II as function
for each step. When the WHAT is too complex the (sub)job
gets broken into a bit more detail of functions I.
This will describe your program in a logical way
without holding up with detail questions.
II HOW is it done
This does the real work in detail. In general you would
go recursively to I to get more description of WHAT
by working out mathematical formulas, formatting data
and so on. You'll break down to I again when during design
you sees more need to describe WHAT is to do and recursive
into II when the HOW is too complex to get done in a single
page.

So evakuating the body of nested or long wounded loops (for, while,
do) into functions of theyr own will remove lots of details from your
brain until you writes the details. You shortens switch statements to
"some different work based on this" is done. You shortens if and else
to "when this condition then this kind of work is to do" without
showing the details until you writes them.

This helps you to avoid lots of
- nested if and else if statements
- gotos (destroying the flow)
- higher nested for/while/do statements
in hiding details fom the flow until you needs them really.

I'm learned that techics in times whereas
- memory was only in amout of KB instead MB available
- assembly was the highest possible programming language
by
- thinking in objects builded of objects builded....
but nothing on help available than my brain to build them
(is there another method to get hudge programms in low memory?)
- need of reuse so many functions as possible
because having every time to less memory available
- having real time work on CPUs having not even 1 single MHz (instead
of xxGHz today).

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Nov 14 '05 #7
In article <20************ *********@compp asch.pi4.lan>,
Felix Kater <f.******@gmx.n et> wrote:
Hi,

when I need to execute a general clean-up procedure (inside of a
function) just before the function returns -- how do I do that when
there are several returns spread over the whole function?
This points to one of the deficits in standard c.
I leave it to others to point to a way out, personally I
would probably use goto here.

The theoretical nice way to do this is, is coroutines, where
a facility and its clean ups can be tied together.
Nobody realizes this nowadays, 'cause when all you have is a hammer...
(I can't elaborate here, without going of topic.)
Thanks
Felix


Groetjes Albert.

--

--
Albert van der Horst,Oranjestr 8,3511 RA UTRECHT,THE NETHERLANDS
One man-hour to invent,
One man-week to implement,
One lawyer-year to patent.
Nov 14 '05 #8

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

Similar topics

14
1537
by: Klaus Neuner | last post by:
Hello, I need to gather information that is contained in various files. Like so: file1: ===================== foo : 1 2 bar : 2 4
0
1003
by: David C. allen | last post by:
I am calling a webclass using the proxy functions generated when I referenced the webclass. When I call the end function for the EndGetBug function the function exits without error on the Dim results() As Object = Me.EndInvoke(asyncResult) line. The EndGetBug = CType(results(0), Bug) line never gets executed. Any ideas why? The Synchronous method that has the same ending line of code executes fine. The following is the function. Public...
15
1630
by: Walter Dnes (delete the 'z' to get my real address | last post by:
A long time ago, in a place far away, there was an OS called DOS that had standard numeric return codes. Regardless of the programming language used, the same error return codes were supposed to be used. See http://www.felgall.com/doserr.htm for a larger list. It starts like so... # 1 Invalid Function Code # 2 File Not Found # 3 Path Not Found # 4 No Handles Available, Too Many Open Files # 5 Access Denied
29
4405
by: keredil | last post by:
Hi, Will the memory allocated by malloc get released when program exits? I guess it will since when the program exits, the OS will free all the memory (global, stack, heap) used by this process. Is it correct?
14
1845
by: Mr Newbie | last post by:
I am often in the situation where I want to act on the result of a function, but a simple boolean is not enough. For example, I may have a function called isAuthorised ( User, Action ) as ????? OK, this function may return a boolean, and if this is true, then no message back is really required, but if it fails then some supporting message needs to be returned to the calling code. As I see it there are a few options.
25
2496
by: lovecreatesbeauty | last post by:
Could you talk something about the general rules on the interface (function) design in C program that recognized publically? Or introduce some good advice of yourself. How do you think about some of those advices like following? a. keep the interface clean and clear (What does clean or clear mean and how to achieve that?). b. avoid using static variables in local function if possible. c. avoid using global variables for local function...
2
2223
by: Jeff | last post by:
Hello, I assigned a new object to a local variable ("req") in a function (see below). The local variable "req" is obviously destroyed when the function exits, but should the object referenced by the variable live on? It seems that it does (and I want it to), but is this correct? I thought that local variables (and objects) are destroyed when the function exits? I declared a callback function--function () {
9
3522
by: tai | last post by:
Hi. I'm looking for a way to define a function that's only effective inside specified function. Featurewise, here's what I want to do: bar_plugin_func = function() { ...; setTimeout(...); ... }; wrap_func(bar_plugin_func); bar_plugin_func(); // calls custom "setTimeout"
5
2269
by: StephQ | last post by:
This is from a thread that I posted on another forum some days ago. I didn't get any response, so I'm proposing it in this ng in hope of better luck :) The standard explanation is that pointer to functions are hard to inline for the compiler, and so you won't be able to avoid function call overhead. This is an important aspect when you are calling a function very frequently for evaluation reason: think of the problem of performing...
4
1179
by: DaTurk | last post by:
Hi, I have this windows app that I'm working on. When it loads it instantiates this object which creates a thread to read data and send it to the form. My problem is, is that I want to keep this thread around for the lifetime of the object, reading and sending data to the from, but it seems to exit when the form completed loading. Why is it doing this? And is there a way I can keep it around after the form loads, without the form...
0
9404
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10009
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9838
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8835
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6651
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5279
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5423
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3929
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3532
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.