Re: <OT> About pointer

From: RCollins (rcoll_at_nospam.theriver.com)
Date: 08/12/04


Date: Wed, 11 Aug 2004 20:47:10 -0700


Chris Torek wrote:

> In article <cfeham$p5a$0@pita.alt.net>
> RCollins <rcoll@nospam.theriver.com> writes:
>
>><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.)

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.

-- 
Ron Collins
Air Defense/RTSC/BCS
"I have a plan so cunning, you could put a tail on it and call it a weasel"


Relevant Pages

  • Re: Strong thread safety and lock free?
    ... you definitely can pack pointer and counter into single word. ... No, there is no emulation of locks, just 2 reference counters ... Automatic alignment but typically no explicit alignment required ... static void debuglog(const char* fmt, ...
    (comp.programming.threads)
  • Re: pass by Reference/value ???
    ... > void foo ... this would be called "passing by reference". ... foo receives a local copy of s and any changes that it makes to s only ... Since s is a pointer, a variable storing the address of s is a pointer to ...
    (comp.lang.cpp)
  • Re: void types and how to use them efficiently?
    ... Where i use void as a generic object. ... this is also used for accessing info structs (per object, ... another approach is what is known as tagged references, ... to resolve the index to a pointer), it usually improves performance for many ...
    (comp.lang.c)
  • Re: basic question about references
    ... It expects a reference, ... not a pointer. ... void f; // a reference ... introduced for operator overloading because using ...
    (alt.comp.lang.learn.c-cpp)
  • Re: confusion: casting function pointers
    ... pointer from the 'actual/other modules' that takes arguments of type ... list to types of void *). ... int main{ ... without a prototype, a number of special "promotion" rules take ...
    (comp.lang.c)