About pointer

W

wilson

Martin Ambuhl said:
^^^^^^^^ int tmp; /* you need an int to store *pa in; 'int *tmp'
declares a pointer, and it doesn't even point
anywhere because it's not initialized. You
could keep your pointer, but only at the
expense of additional code after 'int *tmp;',
for example:
int foobar;
tmp = &foobar;
*/

Thanks, it works.
And now I understand that a "pointer" should be initialized before
storing any value into it.
 
M

Michael Yang

Yes it does something. Because it assigns to *pa and *pb rather than pa
and pb, the changes will be visible in the variables a and b in the
calling function.

It should work below

void swap(int* pa, int* pb){
int* tmp;
tmp=pa;
pa=pb;
pb=tmp;
}


swap(&a, &b);



Don't beat me. I am running away.
 
R

RoSsIaCrIiLoIA

^^^^^^^^^^
*pb = tmp;
Thanks, it works.
And now I understand that a "pointer" should be initialized before
storing any value into it.

void swap(int* a, int* b)
{int temp;
temp = *a;
*a = *b;
*b = temp;
}

Are we all agree?
 
E

Emmanuel Delahaye

Michael Yang wrote on 12/08/04 :
Using pointer here is passing Data by reference.

Not true. In C , all 'passing' are by-value. Even those with a pointer.
The passed value is the address of the object you want to access to.
There is no by-reference passing in C. Pointers are explicit. Always.
I'll fix it like this below

void swap(int* pa, int* pb){
int temp;
temp=*pa;
*pa=*pb;
*pb=temp;
}

Good.
 
R

RCollins

Emmanuel said:
Michael Yang wrote on 12/08/04 :



Not true. In C , all 'passing' are by-value. Even those with a pointer.
The passed value is the address of the object you want to access to.
There is no by-reference passing in C. Pointers are explicit. Always.

<OT>
But for those of us who think in terms of "by reference", what is the
actual difference in passing an arg "by reference" or passing a pointer
to the arg? (Of course, ignoring the C compiler's lack of support for
"by reference").
 
K

Keith Thompson

Emmanuel Delahaye said:
Michael Yang wrote on 12/08/04 :

Not true. In C , all 'passing' are by-value. Even those with a
pointer. The passed value is the address of the object you want to
access to. There is no by-reference passing in C. Pointers are
explicit. Always.

Passing a pointer (by value, of course) is how you implement
pass-by-reference in C.

Saying that passing a pointer isn't really pass-by-reference is like
saying that a call to qsort() isn't really sorting because it doesn't
use a built-in "sort" operator.
 
C

Chris Torek

<OT>
But for those of us who think in terms of "by reference", what is the
actual difference in passing an arg "by reference" or passing a pointer
to the arg? (Of course, ignoring the C compiler's lack of support for
"by reference").
</OT>

This might be better in comp.programming...

There are three common parameter-passing mechanisms for modern
languages: "by value", "by reference", and "value-result". (Algol's
old "by name" method, which is a little tougher to describe, is
hardly ever used because it is so weird.)

True "reference" or "value-result" methods require special compiler
treatment -- usually special syntax -- in which a given function
parameter is designed as such, and then used as if it were an
ordinary variable. One sees this in C++, for instance:

void fn(int &x) {
x = 3;
}

void h(void) {
int i;

fn(i);
/* now i == 3 */
...
}

In C, we have to "manually" simulate the reference argument by
explicitly noting each place at which an underlying pointer mechanism
is used:

void fn(int *x) {
*x = 3; /* note "*" in front of x */
}

void h(void) {
int i;

fn(&i); /* note "&" in front of i */
...
}

The syntax *is* the difference, in other words.

The difference between "reference" and "value-result" is a bit more
subtle. Suppose we have the following C++-like code:

int y = 1;

void fn(int &x) {
x = 3;
printf("at first, x = %d and y = %d\n", x, y);
y = 4;
printf("now x = %d and y = %d\n", x, y);
}

void h(void) {
fn(y);
printf("finally, y = %d\n", y);
}

What does this program fragment print? When we assign a new value
to x in fn(), does that *immediately* change the value of y? When
we assign a new value to y, does that *immediately* change the value
of x?

If we rewrite this in C with explicit pointers, the answers are
clear:

int y = 1;

void fn(int *x) {
*x = 3;
printf("at first, *x = %d and y = %d\n", *x, y);
y = 4;
printf("now *x = %d and y = %d\n", *x, y);
}

void h(void) {
fn(&y);
printf("finally, y = %d\n", y);
}

This program fragment must print:

at first, *x = 3 and y = 3
now *x = 4 and y = 4
finally, y = 4

In other words, both *x and y name the same underlying object,
and updates to EITHER ONE are immediately reflected in BOTH (in
the output).

If our C++-like language used value-result, however, we might
rewrite it in C like this:

int y = 1;
void fn(int *xptr) {
int x = *xptr;

x = 3;
printf("at first, x = %d and y = %d\n", x, y);
y = 4;
printf('now x = %d and y = %d\n", x, y);

*xptr = x;
}

void h(void) {
fn(&y);
}

This program fragment produces very different output, not just
because the "*"s are gone in front of each x:

at first, x = 3 and y = 1
now x = 3 and y = 4
finally, y = 3

In other words, the "final output" from x to *xptr only happens
when we exit the function fn(). The "initial copy" from *xptr to
x only happens when we enter the function. Hence the function fn()
"gets the value" and "returns the result", i.e., has "value-result"
semantics.

C avoids dealing with the issue of whether to use by-reference or
value-result by making the programmer use pointers explicitly.
Other languages define the result (e.g., C++) or leave it up to
the implementor (e.g., Fortran -- F77, at least, prohibits passing
a COMMON-block variable to a subroutine when the subroutine will
both write on the parameter *and* use the same COMMON variable,
since this "exposes the difference" between by-reference and
value-result).
 
R

RCollins

Chris said:
This might be better in comp.programming...

There are three common parameter-passing mechanisms for modern
languages: "by value", "by reference", and "value-result". (Algol's
old "by name" method, which is a little tougher to describe, is
hardly ever used because it is so weird.)

I understand the mechanisms behind "by value" and "by reference";
but I've never heard of "value-result" before.
True "reference" or "value-result" methods require special compiler
treatment -- usually special syntax -- in which a given function
parameter is designed as such, and then used as if it were an
ordinary variable. One sees this in C++, for instance:

void fn(int &x) {
x = 3;
}

void h(void) {
int i;

fn(i);
/* now i == 3 */
...
}

In C, we have to "manually" simulate the reference argument by
explicitly noting each place at which an underlying pointer mechanism
is used:

void fn(int *x) {
*x = 3; /* note "*" in front of x */
}

void h(void) {
int i;

fn(&i); /* note "&" in front of i */
...
}

The syntax *is* the difference, in other words.

That was my point ... passing "by reference" or passing a pointer
"by value" are essentially the same thing. In the "by reference"
case, the compiler is doing the de-reference "behind the scenes"
for the programmer.
The difference between "reference" and "value-result" is a bit more
subtle. Suppose we have the following C++-like code:

int y = 1;

void fn(int &x) {
x = 3;
printf("at first, x = %d and y = %d\n", x, y);
y = 4;
printf("now x = %d and y = %d\n", x, y);
}

void h(void) {
fn(y);
printf("finally, y = %d\n", y);
}

What does this program fragment print? When we assign a new value
to x in fn(), does that *immediately* change the value of y? When
we assign a new value to y, does that *immediately* change the value
of x?

It was my understanding that the C++ "reference" mechanism is the same
'ol "by reference" I learned way way way back.
If we rewrite this in C with explicit pointers, the answers are
clear:

int y = 1;

void fn(int *x) {
*x = 3;
printf("at first, *x = %d and y = %d\n", *x, y);
y = 4;
printf("now *x = %d and y = %d\n", *x, y);
}

void h(void) {
fn(&y);
printf("finally, y = %d\n", y);
}

This program fragment must print:

at first, *x = 3 and y = 3
now *x = 4 and y = 4
finally, y = 4

In other words, both *x and y name the same underlying object,
and updates to EITHER ONE are immediately reflected in BOTH (in
the output).

IMO, one of C's big advantages is the pointer mechanism, where
(when necessary) I can set pointers of various types to the same
memory location (for example, to interpret a floating-point value
as a list of unsigned char).
If our C++-like language used value-result, however, we might
rewrite it in C like this:

int y = 1;
void fn(int *xptr) {
int x = *xptr;

x = 3;
printf("at first, x = %d and y = %d\n", x, y);
y = 4;
printf('now x = %d and y = %d\n", x, y);

*xptr = x;
}

void h(void) {
fn(&y);
}

This program fragment produces very different output, not just
because the "*"s are gone in front of each x:

at first, x = 3 and y = 1
now x = 3 and y = 4
finally, y = 3

In other words, the "final output" from x to *xptr only happens
when we exit the function fn(). The "initial copy" from *xptr to
x only happens when we enter the function. Hence the function fn()
"gets the value" and "returns the result", i.e., has "value-result"
semantics.

C avoids dealing with the issue of whether to use by-reference or
value-result by making the programmer use pointers explicitly.
Other languages define the result (e.g., C++) or leave it up to
the implementor (e.g., Fortran -- F77, at least, prohibits passing
a COMMON-block variable to a subroutine when the subroutine will
both write on the parameter *and* use the same COMMON variable,
since this "exposes the difference" between by-reference and
value-result).

I haven't used Fortran in a while, but isn't this (normally) an
optimizer option? For best optimization, the compiler needs to
avoid "alias'd" values.
 
M

Michael Yang

Michael Yang wrote on 11/08/04 :


Why do you think a pointer is used here ?
Using pointer here is passing Data by reference. Yes, you are right.
I'll fix it like this below

void swap(int* pa, int* pb){
int temp;
temp=*pa;
*pa=*pb;
*pb=temp;
}

swap(&a, &b);
 
R

Richard Bos

RCollins said:
<OT>
But for those of us who think in terms of "by reference", what is the
actual difference in passing an arg "by reference" or passing a pointer
to the arg?

The visibility of it while reading the code. If I read a function in a C
program, say, something like this:

void function(void)
{
int a=2, b=1;

another_function(a, b);

printf("%d\n", a+b);
}

I can rely on this function printing 3. OTOH, if the function reads

void function(void)
{
int a=2, b=1;

another_function(&a, b);

printf("%d\n", a+b);
}

then I know I need to take into account that another_function() could
modify a. In the first case, that is simply impossible, and therefore
not something I need to worry about.

Now consider what could happen if you allow references...
another_function() could, in both cases, modify both a _and_ b, and
there's no way I'm going to find out which without reading its code. The
result is harder maintenance.

Richard
 
R

RCollins

Richard said:
The visibility of it while reading the code. If I read a function in a C
program, say, something like this:

void function(void)
{
int a=2, b=1;

another_function(a, b);

printf("%d\n", a+b);
}

I can rely on this function printing 3. OTOH, if the function reads

void function(void)
{
int a=2, b=1;

another_function(&a, b);

printf("%d\n", a+b);
}

then I know I need to take into account that another_function() could
modify a. In the first case, that is simply impossible, and therefore
not something I need to worry about.

Now consider what could happen if you allow references...
another_function() could, in both cases, modify both a _and_ b, and
there's no way I'm going to find out which without reading its code. The
result is harder maintenance.

Actually, this isn't that much of a handicap. By default, *all* FORTRAN
args are passed "by reference". It's up to the programmer to know
exactly what a called function is about to do to his args. It must
work pretty good, since there's about a ga-zillion FORTRAN programs out
there happily chunking away, day after day after day.
 
B

beliavsky

The visibility of it while reading the code. If I read a function in a C
program, say, something like this:

void function(void)
{
int a=2, b=1;

another_function(a, b);

printf("%d\n", a+b);
}

I can rely on this function printing 3. OTOH, if the function reads

void function(void)
{
int a=2, b=1;

another_function(&a, b);

printf("%d\n", a+b);
}

then I know I need to take into account that another_function() could
modify a. In the first case, that is simply impossible, and therefore
not something I need to worry about.

Now consider what could happen if you allow references...
another_function() could, in both cases, modify both a _and_ b, and
there's no way I'm going to find out which without reading its code. The
result is harder maintenance.

In Fortran 90 you can declare the INTENT of arguments, so a call to a
function
foo such as

function foo(x,y) result(z)
real, intent(in) :: x,y
real :: z
! some code
end function foo

is guaranteed not to change the values of x and y. You do not have to
read the whole function foo to determine this, just the declarations,
which must appear at the top. It is easy to create a pseudo-header
file with this info.

In Fortran 95 you can declare the function to be PURE, which means
that all of its arguments must have intent(in) (and have no other side
effects, such as I/O).
 
J

jmh

RCollins said:
Chris Torek wrote: .. . .


That was my point ... passing "by reference" or passing a pointer
"by value" are essentially the same thing. In the "by reference"
case, the compiler is doing the de-reference "behind the scenes"
for the programmer.

But the address the pointer contains doesn't have to have
anything meaningful in it when passed while the reference,
as I understand pass by reference, must.

jmh
 
C

Chris Torek

I understand the mechanisms behind "by value" and "by reference";
but I've never heard of "value-result" before.

It is often left as an implementation detail in "reference-like"
parameter mechanisms. Value-result arises from a "copy in, then
copy out" form of argument passing. Suppose we have a CPU on
which somewhere from four to eight parameters are passed in
CPU registers, in function calls. A routine h() that calls a
function fn() thus does:

put parameter #1 in P1 (parameter-1) register
put parameter #2 in P2 (parameter-2) register
...
call fn

A C compiler will do this and then ignore the values that are in
the various "P" registers on return, but a value-result compiler
will then copy the P registers back to their original sources:

ld p1,-12(sp) # copy local variable x to p1
ld p2,-40(sp) # copy local variable y to p2
call fn_ # execute the function
st p1,-12(sp) # copy the "x result" back to x
st p2,-40(sp) # copy the "y result" back to y

In the absence of aliases -- i.e., when x and y are not global
variables and fn() has no other "sneaky" way to find them -- it is
impossible to *tell* that this method was used in place of ordinary
"by-reference" (except, perhaps, that the call to the function is
slightly slower, and the function itself runs faster because it
does not have to chase pointers -- or of course by examining the
actual machine code).

If x or y is global, or if functions have "uplevel" access to
outer scope variables (as in Pascal via static links or displays,
or even GNU languages with their weird "trampoline" mechanism
that generates new code at runtime), it becomes possible to
distinguish the underlying parameter-passing mechanism, as I
illustrated earlier.
That was my point ... passing "by reference" or passing a pointer
"by value" are essentially the same thing. In the "by reference"
case, the compiler is doing the de-reference "behind the scenes"
for the programmer.

The thing is that "the compiler does it for you" makes a huge
difference in the end, even though it seems like such a small one
at first.
It was my understanding that the C++ "reference" mechanism is the same
'ol "by reference" I learned way way way back.

It is (I think -- the C++ standards folks are always changing
things :) ).

[aliasing rules in Fortran]
I haven't used Fortran in a while, but isn't this (normally) an
optimizer option? For best optimization, the compiler needs to
avoid "alias'd" values.

In at least the older Fortrans (I have never used anything newer
than F77 myself), it is simply forbidden entirely. If you, as the
Fortran programmer, set things up so that X(I) is the same as Y(J),
or use a COMMON-block variable as a parameter to a routine that
also uses that same COMMON-block variable, the effect is undefined
-- just as things like "i++ + i++" are undefined in C.

The fact that undefined behavior often *changes* when optimizing
(becoming even less predictable than it was without optimization
turned on) is perhaps one of the arguments for making it undefined
in the first place, but not necessarily the only such argument.
To me, this has the same "feeling" (total handwave argument here :) )
as Goedel's incompleteness theorem, in which a mathematical system
is either incomplete or inconsistent.
 
D

Dave Thompson

On 12 Aug 2004 02:20:58 GMT said:
There are three common parameter-passing mechanisms for modern
languages: "by value", "by reference", and "value-result". (Algol's
old "by name" method, which is a little tougher to describe, is
hardly ever used because it is so weird.)

True "reference" or "value-result" methods require special compiler
treatment -- usually special syntax -- in which a given function
parameter is designed as such, and then used as if it were an
ordinary variable. One sees this in C++, for instance: <snip>

Not special syntax where it is the only option, as (classic) FORTRAN,
COBOL, and PL/I, or the default as in later versions of all three. In
modern languages it does tend to be explicit. Except Java where it's
implicit for "object" types and impossible for "primitive" types. And
in Ada it's mostly magic; it may be influenced but not completely
controlled by your choice of in, out, or in out, and sometimes but not
always controlled by type.

And both syntax and semantics are confused in perl -- if you admit
perl as a programming language.
The difference between "reference" and "value-result" is a bit more
subtle. Suppose we have the following C++-like code: <BIG snip>
C avoids dealing with the issue of whether to use by-reference or
value-result by making the programmer use pointers explicitly.
Other languages define the result (e.g., C++) or leave it up to
the implementor (e.g., Fortran -- F77, at least, prohibits passing
a COMMON-block variable to a subroutine when the subroutine will
both write on the parameter *and* use the same COMMON variable,
since this "exposes the difference" between by-reference and
value-result).

Or vice versa; or pass the same actual variable to two different dummy
arguments either of which is written to. (Fortran uses the term
'parameter' for something quite different.) This latter is easier to
avoid at the first level -- it's more obvious if you write FOO (X, X)
than if you write FOO (X) where X is in shared COMMON -- but after
passing through intermediate levels it also is a problem.

And in more recent versions, >= F90, this prohibition is generalized
to also cover variables accessed by MODULEs or "host association"
(routine nesting) or POINTERs, but restricted to permit certain
explicit "aliasable" POINTER and TARGET cases.

In C99 terms it's as if all Fortran arguments (with certain
exceptions) are 'restrict'. Conversely in Fortran terms it's as if C99
'restrict' makes dummies/formals 'correct'. <G><G><G>

- David.Thompson1 at worldnet.att.net
 

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,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top