Assigning stderr to another stream

F

Fred

I start with a program containing

FILE *msgout;
void msgset(FILE*, int);
....
msgset(msgout, 47);

In msgset I have (abbreviated)

FILE *err_stream = NULL;
void msgset(
FILE *msgout,
int iact
)
....
err_stream = stderr;
msgout = err_stream; // Assignment here depends on iact.
return;

In the debugger msgout appears to get set correctly prior to the
return.
Upon return msgout is NULL.
I'm hoping someone can educate me. Thanks,
Fred
 
M

Micah Cowan

Fred said:
I start with a program containing

FILE *msgout;
void msgset(FILE*, int);
...
msgset(msgout, 47);

In msgset I have (abbreviated)

FILE *err_stream = NULL;
void msgset(
FILE *msgout,
int iact
)
...
err_stream = stderr;
msgout = err_stream; // Assignment here depends on iact.
return;

In the debugger msgout appears to get set correctly prior to the
return.
Upon return msgout is NULL.

When you call msgset(), a _copy_ of the global msgout variable assigned
to the parameter named msgout; and a _copy_ of the integral value 47
is assigned to the aprameter named iact. You can assign new values to
iact, just as you assigned a new value to msgout; but both of these
variables are local to the body of msgset(), and will cease to exist
when that function exits, and won't affect anything of the caller's.

To change a variable of the callers, you need to pass in a pointer to
that variable in the fuction call, and dereference it when you assign
from within the function body. Yes, msgout is a pointer, but it's the
FILE *, and not the FILE, that you are trying to change, so it's a
FILE * for which you need to pass a pointer. In other words, what you
need is a FILE **.

...
msgset(&msgout, 47);
...
void msgset(
FILE **msgout,
int iact
)
{
...
*msgout = err_stream;
...
}
 
G

Gordon Burditt

FILE *msgout;
void msgset(FILE*, int);
...
msgset(msgout, 47);

In msgset I have (abbreviated)

FILE *err_stream = NULL;
void msgset(
FILE *msgout,
int iact
)
...
err_stream = stderr;
msgout = err_stream; // Assignment here depends on iact.
return;

In the debugger msgout appears to get set correctly prior to the
return.

You have two variables msgout, one of them is global, and the other
is local to function msgset. Use of the same variable name like
this is confusing.
Upon return msgout is NULL.

C uses pass by value. You may assign to the function parameter
until you are blue in the face, but it won't affect the global
msgout. If you want to change a FILE * in a function, pass the
address of it in (FILE **).

If you wish to assign to the global variable directly, don't use a
function parameter with the same name.
 
F

Fred

Many Thanks. Both of you cleared things up. I just needed to declare
the argument as FILE** and pass in &msgout.
 
M

Micah Cowan

Fred said:
Many Thanks. Both of you cleared things up. I just needed to declare
the argument as FILE** and pass in &msgout.

(And assign to *msgout, but I'm guessing you just forgot to mention
that one.)

I completely agree, though, that it's at least very confusing for you
to have both a global and a local variable that share the same
name. This tends to cause confusion about which variable is being
referred to. I'd actually meant to draw attention to that in my first
response, but forgot to.
 

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
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top