globals again

G

Geometer

Hello!

<Background only>
Globals cannot always be avoided - in OS's with a graphical user interface
functions in an application are called from the OS asynchronously, and if
one of these functions needs the result of another function there seems to
be no way to avoid storing the result of function 1 in some global and
access it later from function 2
</Background only>
My way to deal with this situation is, to put those and only those functions
which need the same bunch of globals together into one compilation unit and
declare the globals for them static and as late as possible like in:
(pseudocode example, not necessarily "real life")

-Is there any better way to do this?

#include <whatever necessary>

static FILE *fp;
static unsigned int stream_ready;
void OpenFile(char *file_name, char mode) /*called when the user requests
the action*/
{
<open the file, store the filepointer and a success indicator>
} /* OpenFile */

static char read_buffer[<SOME_SIZE>];
static size_t buffer_size = sizeof line_buffer;
static int line_complete;
static char *line_buffer;
void ReadLine( size_t buffer_size)
{
char *fgets_result = NULL;
if(stream_ready)
{
fgets_result = fgets(read_buffer, buffer_size, fp);
if(fgets_result)
{
<pre - process the read_buffer, strip '\n', cat with the next line
if no '\n',
allocate memory for the complete line etc>
}
else
{
<the usual eof / error handling>
}
}
else
{
<do the necessary recovery actions>
}
} /* ReadLine */

void ProcessLine(void)
{
<do whatever necessary with the content of the line_buffer>
} /* ProcessLine */

void CloseFile(void)
{
if(fp)
{
fclose(fp);
fp = NULL;
}
} /* CloseFile */


Thank you for taking the time
Robert
 
G

Glenn Hutchings

Geometer said:
Globals cannot always be avoided - in OS's with a graphical user interface
functions in an application are called from the OS asynchronously, and if
one of these functions needs the result of another function there seems to
be no way to avoid storing the result of function 1 in some global and
access it later from function 2

If your callback function did the whole action (open file, read
contents, close it, do something based on contents), instead of just
opening the file, you wouldn't need any globals. At what point are you
going to call your ProcessLine() function?

Glenn
 
B

Bob Martin

in 680917 20060612 073749 "Glenn Hutchings said:
If your callback function did the whole action (open file, read
contents, close it, do something based on contents), instead of just
opening the file, you wouldn't need any globals. At what point are you
going to call your ProcessLine() function?

Glenn

You still need to pass in the file name.
 
G

Geometer

Glenn Hutchings said:
If your callback function did the whole action (open file, read
contents, close it, do something based on contents), instead of just
opening the file, you wouldn't need any globals. At what point are you
going to call your ProcessLine() function?

Hi, Glenn,
First my apologies if this message appears twice - I resend it because
it did not show up for quite a time...

This pseudo-code was just for illustration and my question is more general.
In real life various functions are called either because the user clicks
some control, a timer expires, an i/o operation completes, another
application sends a message or requests data etc. iow everything runs
asynchronously.
Usually the problem comes up, when a user starts an action and then has a
tree of choices
how to proceed, and I am only notified about the kind of the user's choice.
 
S

SuperKoko

Geometer said:
This pseudo-code was just for illustration and my question is more general.
In real life various functions are called either because the user clicks
some control, a timer expires, an i/o operation completes, another
application sends a message or requests data etc. iow everything runs
asynchronously.
Usually the problem comes up, when a user starts an action and then has a
tree of choices
how to proceed, and I am only notified about the kind of the user's choice.

Usually, there is a mean to have a "context" argument passed to a
callback function.
This parameter is used as pointer to a user-defined object.

There are also OO interfaces such as MFC or wxWidgets, where a method
of a class is directly called.

The Win32 API is not very intuitive for that : You must store and
retrieve the user-defined data via SetWindowLong/GetWindowLong using
the GWL_USERDATA index.
Under Windows, you can also register a class and specify extra bytes
for each window (cbWndExtra member of WINDOWCLASS or WINDOWCLASSEX).

Except if an UI system is really badly designed, there should always be
a mean to pass/retrieve a context parameter.
Just read the documentation of your UI system.
 
G

Glenn Hutchings

Bob said:
You still need to pass in the file name.

True... but that can either come from prompting via a modal dialog box
or the text in a widget displayed on the UI somewhere. Still no need
for a global.
 
G

Glenn Hutchings

Geometer said:
This pseudo-code was just for illustration and my question is more general.
In real life various functions are called either because the user clicks
some control, a timer expires, an i/o operation completes, another
application sends a message or requests data etc. iow everything runs
asynchronously.
Usually the problem comes up, when a user starts an action and then has a
tree of choices
how to proceed, and I am only notified about the kind of the user's choice.

For actions where there could be a large time gap between events, yes,
you need to keep track of the current state of things. But sometimes
there are ways other than global variables to do it: for example,
updating a database, or setting the contents of a widget. It's hard to
be specific, because it depends on the situation at hand.

In my own case, I try to avoid getting UI programs to do anything
time-consuming -- the UI just fires up a command-line program and
watches to see when it's finished. So I don't usually run into these
sorts of complexity (and it makes testing a lot simpler :)

Glenn
 

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

Forum statistics

Threads
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top