When a function parameter is a pointer

P

Pol

Hi all,
I am new to C and don't quite understand why in this example the
pointer "FILE *fp" is not passed back to the calling function with its
new value. In its calling routine it seems to be always pointing to
NULL. Could you explain??
Max

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "stdlib.h"
#include "stdio.h"
int i=0;
static int MyOpen(FILE *fp){
if(fp == NULL) fp=fopen("Test.dat","w+");
printf(" Inside %x \n",(unsigned int) fp);
return 0;
}
int main(){
FILE *fp=NULL;
MyOpen(fp);
printf(" First %x \n",(unsigned int) fp);
MyOpen(fp);
printf(" Second %x \n",(unsigned int) fp);
return 0;
}
 
M

Mark Bluemel

Hi all,
I am new to C and don't quite understand why in this example the
pointer "FILE *fp" is not passed back to the calling function with its
new value. In its calling routine it seems to be always pointing to
NULL. Could you explain??
Max

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "stdlib.h"
#include "stdio.h"
int i=0;
static int MyOpen(FILE *fp){
        if(fp == NULL) fp=fopen("Test.dat","w+");
        printf(" Inside %x \n",(unsigned int) fp);
        return 0;}

int main(){
        FILE *fp=NULL;
        MyOpen(fp);
        printf(" First %x \n",(unsigned int) fp);
        MyOpen(fp);
        printf(" Second %x \n",(unsigned int) fp);
        return 0;

}

Your question is a little odd - let me explain why I find it so.

Take this example (not compiled or run, so could have bugs) :-

#include "stdlib.h"
#include "stdio.h"

void f(int x) {
x = 42;
}

int main(void){
int y = 0;
printf(" First %d \n",);
f(y);
printf(" Second %d \n", y);
return 0;
}

I take it you realise that the parameter to f() is passed "by value",
so the change in f() is not seen in main()?

Why should passing a pointer be any different? In your code, the
pointer "fp" is passed by value, so the change made in MyOpen() is not
reflected in main().

This would (should - I haven't compiled or run it) work (I didn't like
your way of printing pointers so I changed it!) :-

include "stdlib.h"
#include "stdio.h"
int i=0;
static int MyOpen(FILE **fpp){ /* File Pointer Pointer as parameter */
if(*fpp == NULL) *fpp=fopen("Test.dat","w+");
printf(" Inside %x \n",(unsigned int) *fpp);
return 0;
}

int main(){
FILE *fp=NULL;
MyOpen(&fp);
printf(" First %p \n", fp);
MyOpen(fp);
printf(" Second %p \n", fp);
return 0;

}
 
D

David RF

Hi all,
I am new to C and don't quite understand why in this example the
pointer "FILE *fp" is not passed back to the calling function with its
new value. In its calling routine it seems to be always pointing to
NULL. Could you explain??
[ ... ]

points to NULL in the first call, and then to Test.dat

if(fp == NULL) fp=fopen("Test.dat","w+")
 
T

Tom St Denis

Your question is a little odd - let me explain why I find it so.

Take this example (not compiled or run, so could have bugs) :-

#include "stdlib.h"
#include "stdio.h"

void f(int x) {
    x = 42;

}

int main(void){
   int y = 0;
   printf(" First %d \n",);
   f(y);
   printf(" Second %d \n", y);
   return 0;

}

I take it you realise that the parameter to f() is passed "by value",
so the change in f() is not seen in main()?

Why should passing a pointer be any different? In your code, the
pointer "fp" is passed by value, so the change made in MyOpen() is not
reflected in main().

This would (should - I haven't compiled or run it) work (I didn't like
your way of printing pointers so I changed it!) :-

include "stdlib.h"
#include "stdio.h"
int i=0;
static int MyOpen(FILE **fpp){ /* File Pointer Pointer as parameter */

Not to get too pedantic but normally that would be referred to as
"pointer to a file pointer" as that conveys more of the meaning of
what it actually is.

Just like "int **x" would be a "pointer to an integer pointer" etc...

Tom
 
M

Mark Bluemel

Not to get too pedantic but normally that would be referred to as
"pointer to a file pointer" as that conveys more of the meaning of
what it actually is.

Yeah, but the "fpp" name and "File Pointer Pointer" expansion was hard
to resist.
 
M

Mark Bluemel

include "stdlib.h"

should be '#include "stdlib.h"' of course
#include "stdio.h"
int i=0;
static int MyOpen(FILE **fpp){ /* File Pointer Pointer as parameter */
        if(*fpp == NULL) *fpp=fopen("Test.dat","w+");
        printf(" Inside %x \n",(unsigned int) *fpp);

better as 'printf(" Inside %p \n",*fpp)
        return 0;

}

int main(){
        FILE *fp=NULL;
        MyOpen(&fp);
        printf(" First %p \n", fp);
        MyOpen(fp);

should be "MyOpen(&fp);" again...
 
B

Ben Bacarisse

Mark Bluemel said:
should be '#include "stdlib.h"' of course

though #include said:
better as 'printf(" Inside %p \n",*fpp)

even better would be printf(" Inside %p \n", (void *)*fpp); though why
that is better is probably down in the noise as far as the OP is
concerned.

<snip>
 
K

Keith Thompson

David RF said:
Hi all,
I am new to C and don't quite understand why in this example the
pointer "FILE *fp" is not passed back to the calling function with its
new value. In its calling routine it seems to be always pointing to
NULL. Could you explain??
[ ... ]

points to NULL in the first call, and then to Test.dat

if(fp == NULL) fp=fopen("Test.dat","w+")

A quibble about terminology:

It really doesn't make much sense to say that a pointer "points to
NULL". A pointer may *be* a null pointer; if so, it doesn't point
to anything. Saying that the pointer *is* NULL makes more sense;
(though that's still not 100% accurate).
 
P

Pol

Your question is a little odd - let me explain why I find it so.

Take this example (not compiled or run, so could have bugs) :-

#include "stdlib.h"
#include "stdio.h"

void f(int x) {
    x = 42;

}

int main(void){
   int y = 0;
   printf(" First %d \n",);
   f(y);
   printf(" Second %d \n", y);
   return 0;

}

I take it you realise that the parameter to f() is passed "by value",
so the change in f() is not seen in main()?

Why should passing a pointer be any different? In your code, the
pointer "fp" is passed by value, so the change made in MyOpen() is not
reflected in main().

This would (should - I haven't compiled or run it) work (I didn't like
your way of printing pointers so I changed it!) :-

include "stdlib.h"
#include "stdio.h"
int i=0;
static int MyOpen(FILE **fpp){ /* File Pointer Pointer as parameter */
        if(*fpp == NULL) *fpp=fopen("Test.dat","w+");
        printf(" Inside %x \n",(unsigned int) *fpp);
        return 0;

}

int main(){
        FILE *fp=NULL;
        MyOpen(&fp);
        printf(" First %p \n", fp);
        MyOpen(fp);
        printf(" Second %p \n", fp);
        return 0;



}

Thank to you all for the helpful comments. I had the false impression
that a pointer, being in itself a reference to some memory position,
was passed by reference and *not* by value. As I said I am fairly new
to C and I come to it from a language where everything is passed by
reference!!
Max
 
N

Nick Keighley

Thank to you all for the helpful comments. I had the false impression
that a pointer, being in itself a reference to some memory position,
was passed by reference and *not* by value. As I said I am fairly new
to C and I come to it from a language where everything is passed by
reference!!

C passses all arguments by value. It uses pointers to emulate call by
reference. Which is either really elegant or really icky depending how
you look at these things.
 
K

Kenny McCormack

C passses all arguments by value. It uses pointers to emulate call by
reference.

The regs will get you for this. To them, you simply can't use the term
"call by reference" in any way, shape, or form, when discussing C.

I remember well the last time this came up. Someone tried to maintain
exactly what you are trying to maintain - that it is useful (in certain
cases) to think of C's strict call-by-value semantics as in some way
"emulating" (or whatever term you prefer) the "call-by-reference"
semantics of other langauges. The regs freakin' had a cow, man! It was
hysterical. They simply could not let it go...

--
No, I haven't, that's why I'm asking questions. If you won't help me,
why don't you just go find your lost manhood elsewhere.

CLC in a nutshell.
 
B

bartc

I remember well the last time this came up. Someone tried to maintain
exactly what you are trying to maintain - that it is useful (in certain
cases) to think of C's strict call-by-value semantics as in some way
"emulating" (or whatever term you prefer) the "call-by-reference"
semantics of other langauges. The regs freakin' had a cow, man! It was
hysterical. They simply could not let it go...

Was that the one about arrays?

C's way of passing arrays works exactly like call-by-reference and nothing
like call-by-value.
 
K

Keith Thompson

bartc said:
C's way of passing arrays works exactly like call-by-reference and nothing
like call-by-value.

Not really.

C's way of passing arrays is that you *cannot* pass arrays, at least not
directly. You can write code that *appears* to be passing an array by
reference, but it's really passing the address of the array's first
element, and of course it passes that address by value.

If I write:

func(arr);

where arr is an array object, the implicit conversion to a pointer
happens before the function call, and has nothing to do with the
fact that arr is a function argument. Exactly the same conversion
happens in other contexts, such as the RHS of an assignment.
 
K

Kenny McCormack

Keith Thompson said:
Not really.

So, Bart, see what I mean?

Really, you'd think that after I'd baited him (and the regs in general)
not to apocalyptic about this, that he'd be able to resist. But, I
guess like the proverbial scorpion (see: The tale of the scorpion and
the frog), he just can't resist his nature.

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...
 
N

Nick Keighley

Was that the one about arrays?

C's way of passing arrays works exactly like call-by-reference and nothing
like call-by-value.

void size_array (int a[])
{
printf ("%d\n", sizeof(a));
}

but code like this doesn't work...
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson wrote:



Neither does NULL!
Right.

"Points to NULL" makes perfect idiomatic sense to me, despite its
supposed meaninglessness. I knew exactly what he was talking
about. Yes, he's using the wrong term, but his misuse is neither
meaningless nor senseless.

Hmm. I knew what he meant, because it is somewhat idiomatic, and
it was sufficiently obvious from context what it was *supposed*
to mean, but I also knew that it didn't make any sense.

The phrase "points to NULL" encourages the idea that a null pointer
points to something. I prefer to make it clear that the whole
purpose of a null pointer is that it doesn't point to anything
at all. (Yes, it's a "pointer" that doesn't "point".)
Saying that you're boiling the kettle is not 100% accurate (or at
least, not normally, anyway). Saying that you're boiling the water
/in/ the kettle makes more sense (although that's still not 100%
accurate), but "boiling the kettle" is nevertheless perfectly good
idiomatic English.

Pointers are not kettles. I'd like to encourage greater precision
and clearer thought when talking about pointers than when talking
about kettles.
For "points to NULL" to be /bad/ idiomatic C, there would have to be
some C-ish or computer-science-ish way in which it could reasonably be
misinterpreted to have some other meaning which would then be cause
for confusion.

void *const p = NULL;
void *points_to_NULL = &p;

In any case, it's not a bad idiom because it's ambiguous. It's a
bad idiom because it's incorrect.
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top