473,468 Members | 1,506 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

segfault w/ block, but not file scope

Hi.

In the snippet of code below, I'm trying to understand why when the

struct dirent ** namelist

is declared with "file" scope, I don't have a problem freeing the
allocated memory. But when the struct is declared in main (block scope)
it will segfault when passing namelist to freeFileNames().

Since this seems to be just a matter of my understanding scope and
pointer parameter passing better, I only included what thought to be
relevant code. I'll happily provide compilable code if deemed necessary.

Please see commented lines:
struct dirent **namelist; /* file scope works */

int main(void)
{
/* struct dirent **namelist */ /* block scope doesn't work */
int n;

n = getFileNames(H5DIR, namelist); /* included from mylib.h */
freeFileNames(namelist, n); /* included from mylib.h */

return 0;
}
Thank you very much for your comments,
Dieter
Jan 6 '06
165 6740
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:
M.B said:

[...]
I've never been to ur. I repeat that C does not have pass by reference.
If you disagree, show me the part of the C Standard that supports your
viewpoint.

C iimplements this by pointers.

In C, pointers are passed by value.


I think M.B has a point,


I don't.
though he didn't state it particularly coherently.


Quite.
No, the C doesn't directly support pass by reference, but, like many
other things, it does support it indirectly.


I don't see that at all. All function argument expressions are evaluated and
those resulting *values* are given to the function concerned. A clearer
case of pass-by-value you could not hope to see.

The reason I think it matters is this: once a newcomer to C works out that
*everything* in C is pass-by-value, it makes the abstract machine much
easier to understand, much more obvious. There is a didactic value in
insisting on what is, after all, only the truth.


Yes, it's important to understand that all function arguments in C are
passed by value. C doesn't have pass-by-reference as a language
feature. But it does support pass-by-reference as a programming
technique.

Suppose I have some Pascal code that uses pass-by-reference (no
guarantee that I've gotten the syntax correct):

function increment(var n: integer)
begin
n := n + 1;
end;

...

n : integer;
n := 42;
increment(n);

The translation to C is straightforward:

void increment(int *n)
{
(*n)++;
}

...

int n;
n = 42;
increment(&n);

Of course you're passing the address of n *by value* to the
increment() function. C doesn't directly support pass-by-reference.
But passing a pointer argument is how you, as a programmer, can
*implement* pass-by-reference.

(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)

Perhaps it would be clearer to use different names for the language
feature and the programming technique. I don't have any good ideas
about that. Since it's such a common technique, it should have a
pithier name than "passing the address of a variable so the function
can use it to modify the value of the variable itself".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #51
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
M.B said:

[...]
I've never been to ur. I repeat that C does not have pass by
reference. If you disagree, show me the part of the C Standard that
supports your viewpoint.
>C iimplements this by pointers.

In C, pointers are passed by value.

I think M.B has a point, though he didn't state it particularly
coherently.
No, the C doesn't directly support pass by reference, but, like many
other things, it does support it indirectly.


In the context of passing a variable 'by reference' so that original
'object' can be altered, c does indeed "pass by reference." In the
context of passing an immutable variable(object) so that the original
'object' remains unaltered has morphed "pass by reference" from it's
original definition since the creation of the concept "pass by
reference" pioneered by early language developers.


[...]

Sorry, but I don't understand what you mean. Are you disagreeing with
my statement that C doesn't support pass by reference indirectly, but
does support it indirectly?

We all know about emulating pass by reference using pointers. If
you're talking about something else, can you provide an example?


I disagree with your assertion that c does not support pass by reference. I
am saying 'pass by reference' meant passing an address to variable memory in a
pointer, which by the way *is* a construct the cpu *knows* how to handle.

"pass by reference', since the creation of c++ and other OOP languages, has
been a new "meaning".
Jan 7 '06 #52
Keith Thompson wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:

M.B said:

[...]

I've never been to ur. I repeat that C does not have pass by reference.
If you disagree, show me the part of the C Standard that supports your
viewpoint.
>C iimplements this by pointers.

In C, pointers are passed by value.

I think M.B has a point,


I don't.

though he didn't state it particularly coherently.


Quite.

No, the C doesn't directly support pass by reference, but, like many
other things, it does support it indirectly.


I don't see that at all. All function argument expressions are evaluated and
those resulting *values* are given to the function concerned. A clearer
case of pass-by-value you could not hope to see.

The reason I think it matters is this: once a newcomer to C works out that
*everything* in C is pass-by-value, it makes the abstract machine much
easier to understand, much more obvious. There is a didactic value in
insisting on what is, after all, only the truth.

Yes, it's important to understand that all function arguments in C are
passed by value. C doesn't have pass-by-reference as a language
feature. But it does support pass-by-reference as a programming
technique.

Suppose I have some Pascal code that uses pass-by-reference (no
guarantee that I've gotten the syntax correct):

function increment(var n: integer)
begin
n := n + 1;
end;

...

n : integer;
n := 42;
increment(n);

The translation to C is straightforward:

void increment(int *n)
{
(*n)++;
}

...

int n;
n = 42;
increment(&n);

Of course you're passing the address of n *by value* to the
increment() function. C doesn't directly support pass-by-reference.
But passing a pointer argument is how you, as a programmer, can
*implement* pass-by-reference.

(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)

Perhaps it would be clearer to use different names for the language
feature and the programming technique. I don't have any good ideas
about that. Since it's such a common technique, it should have a
pithier name than "passing the address of a variable so the function
can use it to modify the value of the variable itself".


It has been twenty years since I coded pascal, I will dispute your pascal code
other than to ask is "increment(1)" syntactically correct and will the pascal
increment() increment memory address 0x0001?
But, the link below gives a good, concrete explanation of "pass by reference"
and "pass by value".

http://csis.pace.edu/~bergin/iticse2000/params.html

In your c code, increment(&n) *is* pass by reference simply because the
original memory can be altered, but I can code an increment() function for
pass by value too.

int increment(int ii) { return(ii+1); }

The original value of ii will remain unaltered, unless of course you code
ii = increment(ii);

Jan 7 '06 #53
Keith Thompson said:
(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)


I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 7 '06 #54
Richard Heathfield wrote:
Keith Thompson said:

(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)

I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.


A pointer can be passed by value, it that address of the memory storing an
address to memory used for "data", or passed by reference to "hide" it memory
address from the function called.

For example, using your allocstr() function called by value;

{
char *t;

allocstr(t,10);
}

Will not have the desired result, char pointer t will remain pointing at it
original ram address both before and after the call to allocstr(). However, I
can pass a reference to t, syntactically &s, that WILL have the desired result.

Further "by value" passing of pointers is strlen() implementation, for example;

int strlen(char *s)
{
int ii;

for(ii=0;*s;ii++);

return(ii);
}

{
char *t = "hello world";

strlen(t);
}

The t variable still points at 'h' because the contents of t is passed by
value, Pointers are primitives in c, just like char, int, and long.
Jan 7 '06 #55
Richard Heathfield wrote:
Keith Thompson said:

(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)

I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.


(Corrected. I'll reread what I type from now on.)

A pointer can be passed by value -- its contents,the address of the memory use
for "data" storage, to "hide" its address from the function called, or the
address location of the pointer itself can be passed by reference to "expose"
its "data content" to modification.

For example, using your allocstr() function called by value;

{
char *t;

allocstr(t,10);
}

Will not have the desired result, char pointer t will remain pointing at it
original ram address both before and after the call to allocstr(). However, I
can pass a reference to t, syntactically &t, that WILL have the desired result.

Further "by value" passing of pointers is strlen() implementation, for example;

int strlen(char *s)
{
int ii;

for(ii=0;*s;ii++);

return(ii);
}

{
char *t = "hello world";

strlen(t);
}

The t variable still points at 'h' because the contents of t is passed by
value, Pointers are primitives in c, just like char, int, and long.

Are we *debating* language syntax or capabilities?
Jan 7 '06 #56
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote: [...]
Suppose I have some Pascal code that uses pass-by-reference (no
guarantee that I've gotten the syntax correct):
function increment(var n: integer)
begin
n := n + 1;
end;
...
n : integer;
n := 42;
increment(n);
The translation to C is straightforward:
void increment(int *n)
{
(*n)++;
}

...

int n;
n = 42;
increment(&n);

It has been twenty years since I coded pascal, I will dispute your
pascal code other than to ask is "increment(1)" syntactically correct
and will the pascal increment() increment memory address 0x0001?


<OT>
No, that's not a problem. In Pascal, for an ordinary (pass-by-value)
parameter, the argument can be any expression of the appropriate type.
For a var (pass-by-reference) parameter, the actual parameter must
be a variable.
</OT>
In your c code, increment(&n) *is* pass by reference simply because
the original memory can be altered, but I can code an increment()
function for pass by value too.


The call increment(&n) passes the *value* of &n. This is used to
implement the equivalent of passing n by reference, something that the
C language doesn't directly support.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #57
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)


I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.


Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct. Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference. Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.

Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #58
Jordan Abel wrote:
On 2006-01-07, Joe Wright <jo********@comcast.net> wrote:
M.B wrote:
Richard Heathfield wrote:
M.B said:

>its a pass by value v/s pass by reference issue

Since C doesn't have pass by reference, it is clear to me that you are
talking nonsense.

I presume u area c++ guy to talk like this.
pass by reference is a generic term for ur info.
C iimplements this by pointers.


M.B., you clearly don't know what 'pass by reference' means. C doesn't
do it, even with pointers. Whether C++ does it is of no interest here.

Yes it does. time() takes its argument by reference [as do many other
functions in time.h, for historical reasons] You are conflating a
generic concept with a specific feature C++ has that C does not.


I may have to look this up because an exact example eludes me right now.
In general, 'pass by reference' means that the argument the callee
receives is the object itself, not a pointer to it. Vague memory has it
that dBASE IV would pass by reference like..

MANY = 0

INCREMENT(MANY)

...would result in MANY being equal 1 because it was MANY, not its value
which is passed to INCREMENT().

PROCEDURE INCREMENT(N)
N = N + 1
RETURN

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jan 7 '06 #59
Joseph Dionne wrote:
Joe Wright wrote:
M.B wrote:
Richard Heathfield wrote:

M.B said:
> its a pass by value v/s pass by reference issue

Since C doesn't have pass by reference, it is clear to me that you are
talking nonsense.

I presume u area c++ guy to talk like this.
pass by reference is a generic term for ur info.
C iimplements this by pointers.


M.B., you clearly don't know what 'pass by reference' means. C doesn't
do it, even with pointers. Whether C++ does it is of no interest here.

Ah, newbies!

Definition of 'pass by reference'

http://publib.boulder.ibm.com/infoce...ef/cplr233.htm


Not a newbie. The above URL is not a definition of 'pass by reference'
but an description of how to fake it.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jan 7 '06 #60
On 2006-01-07, Keith Thompson <ks***@mib.org> wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)


I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.


Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct. Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference. Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.

Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


And uses it extensively in the standard library:

math.h: frexp, modf,
stdio.h: fscanf (and friends), fprintf (and friends, for %n), fgetpos,
fsetpos,
stdlib.h: strtol (and friends),
time.h: mktime, time, asctime, asctime, ctime, gmtime, localtime

Possibly others i've missed from later standards (this was written by
grepping c89 for (.*\*.*) and manually selecting the functions that use
this mechanism.
Jan 7 '06 #61
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:


[...]
Suppose I have some Pascal code that uses pass-by-reference (no
guarantee that I've gotten the syntax correct):
function increment(var n: integer)
begin
n := n + 1;
end;
...
n : integer;
n := 42;
increment(n);
The translation to C is straightforward:
void increment(int *n)
{
(*n)++;
}

...

int n;
n = 42;
increment(&n);


It has been twenty years since I coded pascal, I will dispute your
pascal code other than to ask is "increment(1)" syntactically correct
and will the pascal increment() increment memory address 0x0001?

<OT>
No, that's not a problem. In Pascal, for an ordinary (pass-by-value)
parameter, the argument can be any expression of the appropriate type.
For a var (pass-by-reference) parameter, the actual parameter must
be a variable.
</OT>
In your c code, increment(&n) *is* pass by reference simply because
the original memory can be altered, but I can code an increment()
function for pass by value too.

The call increment(&n) passes the *value* of &n. This is used to
implement the equivalent of passing n by reference, something that the
C language doesn't directly support.


The *value* of a long is memory big enough to hold a define number data bits,
same for the *value* of int, and char variables. The *value* of a pointer
variable is the number of bits needed to hold a memory address, a special
purpose "integer" if you will. Admittedly, this duality is confusing.

I believe the confusion, and abuse of pointers derives from the duality in
nature of a pointer. Sure, one can "read/write" to a pointer, the it is the
"magic" of automatic dereferencing by the compiler. The pointer variable only
contains a memory address.

That is not to be confused that a pointer's value, the memory address of the
data to which it points, can be passed by reference or by value, regardless of
the syntax by which this is done.
Jan 7 '06 #62
Keith Thompson wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
(I'm 100% certain that I'm not telling you anything you don't already
know; the point is to figure out just where we disagree.)


I'm for whatever makes C easier to understand. Heaven knows it's hard enough
already, without making it harder.

When you say "pointers" and "pass by reference", yes, OF COURSE I know what
you mean. But J Random Newbie over there, who already has a hundred new
concepts buzzing around his head right now and who does not fully
understand what pointers *are* yet, let alone what they are *for*, is going
to think "pointers, right, the little * thing, okay, pass-by-reference,
right, * means pass by reference, which means I can update it, great..."
and he is going to think he understands things a little better - and then
he is (eventually) going to wonder why this:

void allocstr(char *s, size_t n)
{
s = malloc(n);

if(s == NULL) abort();
}

doesn't seem to do what he wants.

Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct. Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference. Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.

Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


Yes it does! The "language construct" is simply not one character, but two "&n".

Jan 7 '06 #63
Joe Wright wrote:
Joseph Dionne wrote:
Joe Wright wrote:
M.B wrote:

Richard Heathfield wrote:

> M.B said:
>
>
>> its a pass by value v/s pass by reference issue
>
>
>
>
> Since C doesn't have pass by reference, it is clear to me that you are
> talking nonsense.
>
>

I presume u area c++ guy to talk like this.
pass by reference is a generic term for ur info.
C iimplements this by pointers.
M.B., you clearly don't know what 'pass by reference' means. C
doesn't do it, even with pointers. Whether C++ does it is of no
interest here.

Ah, newbies!

Definition of 'pass by reference'

http://publib.boulder.ibm.com/infoce...ef/cplr233.htm

Not a newbie. The above URL is not a definition of 'pass by reference'
but an description of how to fake it.


Whatever!
Jan 7 '06 #64
On Sat, 07 Jan 2006 21:42:11 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:
We all know about emulating pass by reference using pointers. If
you're talking about something else, can you provide an example?

I disagree with your assertion that c does not support pass by reference.

snip"pass by reference', since the creation of c++ and other OOP languages, has
been a new "meaning".


This may be so, but the current meaning is the one that is current.
Once upon a time gay meant happy, and eye meant egg. You can see there
is opportunity for considerable confusion by using an archaic meaning.
Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Jan 7 '06 #65
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
The *value* of a long is memory big enough to hold a define number
data bits, same for the *value* of int, and char variables.
Ok. (One could question whether values are made of bits, but let's
not get into that.)
The *value* of a pointer variable is the number of bits needed to
hold a memory address, a special purpose "integer" if you will.
No, I won't. Pointers are not integers. Pointers are pointers.
Admittedly, this duality is confusing.
The value of a pointer variable is a pointer value, also known as an
address. I don't know what duality you're referring to. Pointers and
integers are different things. One of the operations you can perform
on a pointer, dereferencing, happens to give you the value of what it
points to. As long as you keep this straight, it shouldn't be all
that confusing.
I believe the confusion, and abuse of pointers derives from the
duality in nature of a pointer. Sure, one can "read/write" to a
pointer, the it is the "magic" of automatic dereferencing by the
compiler. The pointer variable only contains a memory address.
What automatic dereferencing are you referring to? In C, pointers are
not implicitly dereferenced; that's what the unary "*" operator is
for. Can you provide an example, in C code, of what you're talking
about?
That is not to be confused that a pointer's value, the memory address
of the data to which it points, can be passed by reference or by
value, regardless of the syntax by which this is done.


The value of a pointer (an address) can be passed *by value*. You can
effectively pass a pointer value by reference if you pass a
pointer-to-pointer; then you're passing the pointer-to-pointer by
value.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #66
Joseph Dionne wrote:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:

[...]
Suppose I have some Pascal code that uses pass-by-reference (no
guarantee that I've gotten the syntax correct):
function increment(var n: integer)
begin
n := n + 1;
end;
...
n : integer;
n := 42;
increment(n);
The translation to C is straightforward:
void increment(int *n)
{
(*n)++;
}

...

int n;
n = 42;
increment(&n);
It has been twenty years since I coded pascal, I will dispute your
pascal code other than to ask is "increment(1)" syntactically correct
and will the pascal increment() increment memory address 0x0001?


<OT>
No, that's not a problem. In Pascal, for an ordinary (pass-by-value)
parameter, the argument can be any expression of the appropriate type.
For a var (pass-by-reference) parameter, the actual parameter must
be a variable.
</OT>
In your c code, increment(&n) *is* pass by reference simply because
the original memory can be altered, but I can code an increment()
function for pass by value too.


The call increment(&n) passes the *value* of &n. This is used to
implement the equivalent of passing n by reference, something that the
C language doesn't directly support.


The *value* of a long is memory big enough to hold a define number data
bits, same for the *value* of int, and char variables. The *value* of a
pointer variable is the number of bits needed to hold a memory address,
a special purpose "integer" if you will. Admittedly, this duality is
confusing.

I believe the confusion, and abuse of pointers derives from the duality
in nature of a pointer. Sure, one can "read/write" to a pointer, the it
is the "magic" of automatic dereferencing by the compiler. The pointer
variable only contains a memory address.

That is not to be confused that a pointer's value, the memory address of
the data to which it points, can be passed by reference or by value,
regardless of the syntax by which this is done.


And, the whole topic gets even more confusing because of privative arrays,
i.e. int ii[5]. Here ii is "handled" as *both* a pointer and real memory
storage. Obviously one does not assign to the ii[] with "ii = 0" but uses a
subscript to isolate one int's actually memory storage address, i.e. "ii[0] =
0". However to pass the ii[] to a function(int *), the call can be simply
coded as "function((int *)ii)" with the cast only needed to fake out
prototyping compilers.
Jan 7 '06 #67
Mark McIntyre wrote:
On Sat, 07 Jan 2006 21:42:11 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:

We all know about emulating pass by reference using pointers. If
you're talking about something else, can you provide an example?


I disagree with your assertion that c does not support pass by reference.


snip
"pass by reference', since the creation of c++ and other OOP languages, has
been a new "meaning".

This may be so, but the current meaning is the one that is current.
Once upon a time gay meant happy, and eye meant egg. You can see there
is opportunity for considerable confusion by using an archaic meaning.
Mark McIntyre


So when enough people refer to the period from sunrise to sunshine (the day)
as night, we all need to use their incorrect definition?
Jan 7 '06 #68
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:

[...]
Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct. Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference. Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.
Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


Yes it does! The "language construct" is simply not one character,
but two "&n".


You're making Richard's point that we shouldn't talk about pass by
reference in C.

&n is simply an expression consisting of a unary "&" operator and an
identifier; it yields the address of n. *p is an expression
consisting of a unary "*" operator and an identifier; it dereferences
the pointer p and yields the value of the object it points to. These
constructs can be combined to implement the programming technique
known as pass by reference.

If you want to think of

void increment(int *p) ... increment(&n);

as "pass by reference", that's fine -- but you *must* understand that
it's built from lower-level constructs.

Note that a function with exactly the same interface:

void check_for_null(int *p)
{
if (p == NULL) {
fprintf(stderr, "p is a null pointer\n");
}
}

has nothing to do with pass by reference; it simply takes a pointer
parameter which is passed by value. Pointers aren't magical; they're
simply types with a particular set of operations that can be applied
to them.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #69
On Sat, 07 Jan 2006 23:23:22 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:
Mark McIntyre wrote:
On Sat, 07 Jan 2006 21:42:11 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:
"pass by reference', since the creation of c++ and other OOP languages, has
been a new "meaning".


This may be so, but the current meaning is the one that is current.


So when enough people refer to the period from sunrise to sunshine (the day)
as night, we all need to use their incorrect definition?


If you want to avoid confusion, and being thought of as a pompous ass,
yes IMHO. YMMV. HAND.

Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Jan 7 '06 #70
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
The *value* of a long is memory big enough to hold a define number
data bits, same for the *value* of int, and char variables.

Ok. (One could question whether values are made of bits, but let's
not get into that.)

The *value* of a pointer variable is the number of bits needed to
hold a memory address, a special purpose "integer" if you will.

No, I won't. Pointers are not integers. Pointers are pointers.

Admittedly, this duality is confusing.

The value of a pointer variable is a pointer value, also known as an
address. I don't know what duality you're referring to. Pointers and
integers are different things. One of the operations you can perform
on a pointer, dereferencing, happens to give you the value of what it
points to. As long as you keep this straight, it shouldn't be all
that confusing.


I can increment the memory address of the pointer, or I can alter the memory
to which the pointer points. This is not true for a privative long variable
who can only have it data altered. That is the "duality" of which I speak.
I believe the confusion, and abuse of pointers derives from the
duality in nature of a pointer. Sure, one can "read/write" to a
pointer, the it is the "magic" of automatic dereferencing by the
compiler. The pointer variable only contains a memory address.

What automatic dereferencing are you referring to? In C, pointers are
not implicitly dereferenced; that's what the unary "*" operator is
for. Can you provide an example, in C code, of what you're talking
about?


Using my strlen() example;

int strlen(char *s)
{
int ii;
for(ii=0;*s;ii++,s++) ;
return(ii);
}

{
char *t;

strlen(t);
}

One would "think" the strlen call would be "strlen(&t)" but that is incorrect
because the compiler "knows" t is already a pointer. The same is true for
this usage of a "pointer."

{
char a[32] = "hello world";

strlen(a);
}

Again the compiler *considers* a a pointer even though in fact it is simple
"label," as in assembler, to *mark* the start of a block of memory.
That is not to be confused that a pointer's value, the memory address
of the data to which it points, can be passed by reference or by
value, regardless of the syntax by which this is done.

The value of a pointer (an address) can be passed *by value*. You can
effectively pass a pointer value by reference if you pass a
pointer-to-pointer; then you're passing the pointer-to-pointer by
value.


So, your definition of "pass by reference" would be if *not* passing a pointer
to a pointer by value?
Jan 8 '06 #71
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:
[...]
Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct. Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference. Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.
Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


Yes it does! The "language construct" is simply not one character,
but two "&n".

You're making Richard's point that we shouldn't talk about pass by
reference in C.

&n is simply an expression consisting of a unary "&" operator and an
identifier; it yields the address of n. *p is an expression
consisting of a unary "*" operator and an identifier; it dereferences
the pointer p and yields the value of the object it points to. These
constructs can be combined to implement the programming technique
known as pass by reference.


No way! '&' is a bit wise logical AND, to get the contents of a pointer, one
codes it as "&pointer" not "& pointer" which will generate an error.

If you want to think of

void increment(int *p) ... increment(&n);

as "pass by reference", that's fine -- but you *must* understand that
it's built from lower-level constructs.

Note that a function with exactly the same interface:

void check_for_null(int *p)
{
if (p == NULL) {
fprintf(stderr, "p is a null pointer\n");
}
}

has nothing to do with pass by reference; it simply takes a pointer
parameter which is passed by value. Pointers aren't magical; they're
simply types with a particular set of operations that can be applied
to them.

Jan 8 '06 #72
Mark McIntyre wrote:
On Sat, 07 Jan 2006 23:23:22 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:

Mark McIntyre wrote:
On Sat, 07 Jan 2006 21:42:11 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:
"pass by reference', since the creation of c++ and other OOP languages, has
been a new "meaning".

This may be so, but the current meaning is the one that is current.


So when enough people refer to the period from sunrise to sunshine (the day)
as night, we all need to use their incorrect definition?

If you want to avoid confusion, and being thought of as a pompous ass,
yes IMHO. YMMV. HAND.

Mark McIntyre


Sorry, Mr. McIntyre, software is a precision art, not hand grenades or
horseshoes. It has a history of development that ought not be forgotten or
convoluted by future misrepresentations simply because the originating concept
is difficult to grasp.

IHMO, and HAND to you.
Jan 8 '06 #73
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
The *value* of a long is memory big enough to hold a define number
data bits, same for the *value* of int, and char variables. Ok. (One could question whether values are made of bits, but let's
not get into that.)
The *value* of a pointer variable is the number of bits needed to
hold a memory address, a special purpose "integer" if you will.

No, I won't. Pointers are not integers. Pointers are pointers.
Admittedly, this duality is confusing.

The value of a pointer variable is a pointer value, also known as an
address. I don't know what duality you're referring to. Pointers and
integers are different things. One of the operations you can perform
on a pointer, dereferencing, happens to give you the value of what it
points to. As long as you keep this straight, it shouldn't be all
that confusing.


I can increment the memory address of the pointer, or I can alter the
memory to which the pointer points. This is not true for a privative
long variable who can only have it data altered. That is the
"duality" of which I speak.


I'm sorry, but I really have no idea what you mean by "a privative
long variable who can only have it data altered". Does "privative"
mean "private" or "primitive"? Does "long" refer to the standard
integer type by that name, or something else? I'm not aware of any
data type on which the only operation you can perform is to alter its
data; such a thing wouldn't be terribly useful.

Duality between what and what, exactly?

The language defines certain operations on pointers, including
dereferencing and a limited set of arithmetic operators. (Some other
languages don't support pointer arithmetic, but we're talking about
C.) The fact that you can perform arithmetic on pointers doesn't
imply that pointers are some kind of integers. They can be
implemented that way, but as far as the language is concerned a
pointer is a pointer and an integer is an integer; conversions between
the two are possible, but the results are implementation-defined.

[...]
Using my strlen() example;

int strlen(char *s)
{
int ii;
for(ii=0;*s;ii++,s++) ;
return(ii);
}

{
char *t;

strlen(t);
}

One would "think" the strlen call would be "strlen(&t)" but that is
incorrect because the compiler "knows" t is already a pointer.
Why on Earth would one expect the strlen call to be strlen(&t)? The
function expects an argument of type char*, and t is an object of type
char*, so the call should be strlen(t). Don't make it more
complicated than it is.
The same is true for this usage of a "pointer."

{
char a[32] = "hello world";

strlen(a);
}

Again the compiler *considers* a a pointer even though in fact it is
simple "label," as in assembler, to *mark* the start of a block of
memory.


Don't think of it as a "label" as in assembler.

a is an array object. An expression of array type, in most contexts,
is implicitly converted to a pointer to its first element; the
exceptions are the operand of a unary "sizeof" or "&" operator and a
string literal used to initialize an array. So the expression a is of
type char*, which is the expected argument thpe for strlen. Once you
understand this, there's no real problem.

You might want to review sections 4, 5, and C of the comp.lang.c FAQ
at <http://www.c-faq.com/>.
That is not to be confused that a pointer's value, the memory address
of the data to which it points, can be passed by reference or by
value, regardless of the syntax by which this is done.

The value of a pointer (an address) can be passed *by value*. You
can effectively pass a pointer value by reference if you pass a
pointer-to-pointer; then you're passing the pointer-to-pointer by
value.


So, your definition of "pass by reference" would be if *not* passing a
pointer to a pointer by value?


The term "pass by reference" can refer to two different things. One
is a language feature (that doesn't exist in C). The other is a
programming technique that can implemented in C by using pointers.
(It's been argued that this shouldn't be referred to as pass by
reference.)

You can't *directly* pass anything by reference in C. If you want to
emulate passing something by reference, the way to do that is to use a
pointer. In general, to emulate passing a FOO by reference, you do it
by passing a FOO* (a pointer-to-FOO) by value. It doesn't matter what
FOO is; you pass an int by reference by passing a pointer-to-int, you
pass a struct by reference by passing a pointer-to-struct, and you
pass a pointer-to-whatever by reference by passing a
pointer-to-pointer-to-whatever.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #74
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
And, the whole topic gets even more confusing because of privative
arrays, i.e. int ii[5]. Here ii is "handled" as *both* a pointer and
real memory storage.
No, it's an array, but its name is implicitly converted to a pointer
value in most contexts. (There is no pointer object involved.)
Obviously one does not assign to the ii[] with
"ii = 0" but uses a subscript to isolate one int's actually memory
storage address, i.e. "ii[0] = 0". However to pass the ii[] to a
function(int *), the call can be simply coded as "function((int *)ii)"
with the cast only needed to fake out prototyping compilers.


Given the declaration
int ii[5];
the expression
ii
is already of type int*. Casting it to int* is unnecessary and
potentially dangerous.

All modern C compilers are "prototyping", if that means that they
support function prototypes. If you can show us an example where you
think it's necessary to "fake out" the compiler, we can probably
explain why it's unnecessary and/or a bad idea.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #75
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
No way! '&' is a bit wise logical AND, to get the contents of a
pointer, one codes it as "&pointer" not "& pointer" which will
generate an error.


I'm beginning to suspect that you may be a deliberate troll. Do you
seriously believe that what you've just written above is correct? I
don't mean to be insulting, but the number of fundamental errors in
that paragraph is astonishing.

There are two "&" operators in C, a binary operator (taking two
operand) that performs a bitwise logical AND, and a unary operator
(taking one operand) that yields the address of its operand.

The expressions "&pointer" and "& pointer" are precisely equivalent.
The amount of whitespace between the operator and the operand is not
significant. The compiler is able to distinguish between unary and
binary "&" by the context in which it appears.

The unary "&" operator doesn't yield the contents of a pointer; it
yields the address of an object.

I suggest you read a good C textbook (K&R2 is very good). You have a
lot of things to unlearn.

(Or if you're doing this deliberately, please please please go away;
it's not amusing.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #76
In article <9R*****************@newsread1.news.atl.earthlink. net>
and numerous others, Joseph Dionne <jd*****@hotmail.com> wrote ...
well, a whole lot, not too much of it especially good, about whether
C has "pass by reference".

The key item that C lacks -- but C++ and Pascal have, that make
those two languages actually possess pass-by-reference -- is an
"implicit dereference".

In Pascal, we can write (where T is some type, either one predefined
by the language or one we have defined ourselves):

procedure foo(var n : T); begin
... operate on n ...
end;

In C++, we can write:

void foo(T & n) {
... operate on n ...
}

In both cases, we cannot, in foo(), "re-bind" n to refer to some
other variable. It always and forever -- or at least until foo()
returns, so that it ceases to exist -- refers to the parameter
supplied by the caller. This is a useful and common property of
language-provided pass-by-reference, but (I claim) not actually
necessary.

More importantly, in both cases, in order to change the caller's
variable, we do something like this in foo():

n = 42; /* for C++; in Pascal, use n := 42 */

Note that we do not adorn the variable name "n" with any special
punctuators or operators here. We use the same syntax we would
use if n were a local variable. (I include this second sentence
because in some languages, for which one might argue whether they
possess by-reference arguments, even ordinary local variables
require some sort of punctuation in order to assign values to
them.)

In both cases, the caller then does nothing to distinguish the
by-reference call from a by-value call:

foo(x); /* modifies x */
bar(x); /* does not modify x */

This means the programmer must know whether any given function or
procedure modifies any of its arguments. (It is not clear to me
that this last is a *required* property. If there were a language
in which the declaration and/or definition of foo() itself made it
clear that a parameter n was by-reference, but also forced callers
to acknowledge the by-reference call, would the language meet the
definition of "by reference" calls? I am not aware of any such
language, and without one, I think the question is moot.)

In C, by contrast, in order for a funtion foo() to change its
caller's variable, we must adorn not only the call:

foo(&x); /* permits foo to modify x */

but more importantly, we must decorate every use of "n" within
foo() itself:

void foo(T * n) {
... operate on *n ...
}

If, within foo(), we attempt to operate on "n" instead of "*n",
we "re-bind" n to point to some other object of type T. This is
impossible in Pascal and C++ (and Fortran at least through F77,
for that matter, although Fortran allows value-result instead
of by-reference).

Mr Dionne appears to believe that C's arrays are an exception, and
are passed by reference. While C's arrays *are* exceptional, this
is not where the exception occurs. C remains pass-by-value. The
gimmick is that the "value" of an array is a pointer to the array's
first element. In:

void f(void) {
char buf[100];
char *p;

p = buf;

we attempt to copy the "value" of buf -- an array -- to the pointer
variable p. The "value" of the array is a pointer to the array's
first element, so this sets p to point to &buf[0]. Likewise, if we
go on to call a function g() and pass the "value" of buf:

g(buf);
...
}

then g() receives, as its value, a pointer to the array's first
element -- a pointer to buf[0]. Within g(), as for any simulation
of by-reference in C, we have to use the unary "*" operator in
order to write to buf[0]:

void g(char * ptr) {
* ptr = 42;
...
}

and if we fail to prefix "ptr" with the unary "*" operator when
assigning, we will "re-bind" it so that it no longer points to
"buf" at all:

ptr = "oops";

Now *ptr is no longer 42 (in any current character set anyway):
ptr now points to the first element of an anonymous (unnamed) array
of 5 "char"s that are set to {'o','o','p','s','\0'} and must not
be changed (they may or may not actually be read-only, but the
effect of attempting to change them is undefined).

The sneaky part of this is that, given a pointer to buf[0] -- and
no reassignment of ptr itself, i.e., leave out the "oops" line --
we can use that pointer to access buf[1] through buf[99] as well.
That is why, in f() and g() both, we can do:

p[23] = 'x'; /* in f() */

or:

ptr[24] = 'y'; /* in g() */

None of this has much to do with calling mechanisms. The array /
pointer interconversion rules in C happen long before any concerns
with parameter-passing. It is merely the case that, because calls
*are* by-value and the "value" of an array is a pointer to its
first element, function calls are a very common point at which
the interconversion occurs.

The other syntactic gimmick that trips people up is that C allows
the programmer to lie about certain parameter types. If some
function receives a pointer of type "pointer to T", the programmer
is allowed to declare the formal parameter *as if* it had type
"array N of T". (The array size can be included or omitted.
Except for the new C99 meaning for "static", the size is not
used.) Hence, we can write the following:

#include <stdio.h>

void h(char paramvar[100]) {
char localvar[100];

printf("sizeof paramvar: %lu\n",
(unsigned long)sizeof paramvar);
printf("sizeof localvar: %lu\n",
(unsigned long)sizeof localvar);
}

Actually *executing* this function, however, is instructive:
the output is typically:

sizeof paramvar: 4 (or sometimes 2 or 8; rarely, 1)
sizeof localvar: 100 (always exactly 100)

In addition, we can demonstrate that "paramvar" actually has type
"char *" -- not "char [100]" -- by re-binding it:

void h(char paramvar[100]) {
char localvar[100];
char other[100];

printf("sizeof paramvar: %lu\n",
(unsigned long)sizeof paramvar);
printf("sizeof localvar: %lu\n",
(unsigned long)sizeof localvar);
paramvar = localvar; /* OK */
localvar = other; /* ERROR */
}

A diagnostic is required (and occurs) for the assignment to localvar,
because arrays are not modifiable lvalues (although the form of
the error message is not dictated by the standard and it is often
a bit peculiar). No diagnostic is required, and generally none
occurs, for the assignment to paramvar, because it is not an array;
its type is "char *", not "char [100]".

The Standard actually says that the type is to be rewritten by the
compiler:

... A
declaration of a parameter as ``array of type'' shall be
adjusted to ``pointer to type,'' and a declaration of a
parameter as ``function returning type'' shall be adjusted
to ``pointer to function returning type,'' as in 6.2.2.1.

(C99 draft, section 6.7.1). (The second part of the sentence above
means that you can define a function that takes another function,
instead of using the function-pointer syntax:

void operate(T f(args));

and

void operate(T (*f)(args));

mean the same thing in a prototype, and either version can be used
in the definition of the function "operate".)

Finally, it is worth pointing out that, in languages that have or
allow by-reference function calls, it may (or may not, depending on
the language definition) be possible to discover whether the compiler
actually uses by-reference, or simulates it with value-result. The
following C++ program fragment (though using printf() instead of cout)
illustrates a feature of by-reference:

int globalvar;

void f(int& x) {
x = 42;
printf("globalvar is now %d\n", globalvar);
x = 43;
}

int main(void) {
globalvar = 1;
f(globalvar);
printf("globalvar is now %d\n", globalvar);
}

The output of this program *must* be:

globalvar is now 42
globalvar is now 43

If this program is converted to Fortran 77 in the obvious way,
the effect of the program becomes undefined. Actually running it
may produce:

globalvar is now 1
globalvar is now 43

In this case, the compiler used value-result. This value-result
mechanism can be simulated in C as:

int globalvar;

void f(int *xp) {
int x = *xp;

x = 42;
printf("globalvar is now %d\n", globalvar);
x = 43;

*xp = x;
}

int main(void) {
globalvar = 1;
f(&globalvar);
printf("globalvar is now %d\n", globalvar);
}

The difference between by-reference and value-result is that, in
by-reference every occurrence of the apparently-ordinary variable
within a given function/procedure is -- at least before optimization
-- turned into an appropriate dereference. In the value-result
case, however, the value is passed to the callee, and the callee
returns a new result to be stored back in the original variable.
The effect is that there is a single dereference at entry to the
function/procedure, and a second one at exit. (Whether the copy
occurs in the callee, as in the C simulation, or the caller, is up
to the compiler -- the difference is not generally detectable.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 8 '06 #77
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
No way! '&' is a bit wise logical AND, to get the contents of a
pointer, one codes it as "&pointer" not "& pointer" which will
generate an error.

I'm beginning to suspect that you may be a deliberate troll. Do you
seriously believe that what you've just written above is correct? I
don't mean to be insulting, but the number of fundamental errors in
that paragraph is astonishing.

There are two "&" operators in C, a binary operator (taking two
operand) that performs a bitwise logical AND, and a unary operator
(taking one operand) that yields the address of its operand.

The expressions "&pointer" and "& pointer" are precisely equivalent.
The amount of whitespace between the operator and the operand is not
significant. The compiler is able to distinguish between unary and
binary "&" by the context in which it appears.

The unary "&" operator doesn't yield the contents of a pointer; it
yields the address of an object.

I suggest you read a good C textbook (K&R2 is very good). You have a
lot of things to unlearn.

(Or if you're doing this deliberately, please please please go away;
it's not amusing.)


It is just as amusing as you assertion, backed by no well known authority of
the c language specification, that c does not support pass by reference.

Your continued reference to 'object' during replies proves my assertions --
recent OOP development (decades ago implemented recent, I mean) have
obfuscated the meaning of "pass by reference". I suspect this is due mostly
to the declining software knowledge, and skills, that has again raised the
acclaim and praise for "garbage collection" languages.

Show me any authority that shares you "opinion" that c does not "pass by
reference".
Jan 8 '06 #78
Chris Torek wrote:

[..]
Mr Dionne appears to believe that C's arrays are an exception, and
are passed by reference. While C's arrays *are* exceptional, this
is not where the exception occurs. C remains pass-by-value. The
gimmick is that the "value" of an array is a pointer to the array's
first element. In:

void f(void) {
char buf[100];
char *p;

p = buf;

we attempt to copy the "value" of buf -- an array -- to the pointer
variable p. The "value" of the array is a pointer to the array's
first element, so this sets p to point to &buf[0]. Likewise, if we
go on to call a function g() and pass the "value" of buf:

g(buf);
...
}

then g() receives, as its value, a pointer to the array's first
element -- a pointer to buf[0]. Within g(), as for any simulation
of by-reference in C, we have to use the unary "*" operator in
order to write to buf[0]:

void g(char * ptr) {
* ptr = 42;
...
}

and if we fail to prefix "ptr" with the unary "*" operator when
assigning, we will "re-bind" it so that it no longer points to
"buf" at all:

ptr = "oops";

Now *ptr is no longer 42 (in any current character set anyway):
ptr now points to the first element of an anonymous (unnamed) array
of 5 "char"s that are set to {'o','o','p','s','\0'} and must not
be changed (they may or may not actually be read-only, but the
effect of attempting to change them is undefined).


Look who is being humorous. Sir, in you example, "buf" will never change is
memory value, even *if* you pass it by reference, "& buf". You might cause a
program error, but buf will forever point to the same memory address.
[..]

I think we all can agree the pascal and c++ support pass by reference by
different syntax. I assert the c uses yet another syntax to implement pass by
reference, nothing more or less.
Jan 8 '06 #79
Joseph Dionne wrote:
.... big fat snip ...
It has been twenty years since I coded pascal, I will dispute
your pascal code other than to ask is "increment(1)"
syntactically correct and will the pascal increment() increment
memory address 0x0001?


No it isn't correct, and should provoke an error similar to
"Attempt to load the address of an expression".

In general pass by reference passes by referring to the thing to be
passed, not to its address. C does not do this. The caller has to
pass the address, often by an & operator. The user has the choice
of operating on that address (a no-no for pass by reference) or of
dereferencing it with the * operator.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 8 '06 #80
On 2006-01-08, Joseph Dionne <jd*****@hotmail.com> wrote:

It is just as amusing as you assertion, backed by no well known authority of
the c language specification, that c does not support pass by reference.

Your continued reference to 'object' during replies proves my assertions --
recent OOP development (decades ago implemented recent, I mean) have
obfuscated the meaning of "pass by reference". I suspect this is due mostly
to the declining software knowledge, and skills, that has again raised the
acclaim and praise for "garbage collection" languages.

Show me any authority that shares you "opinion" that c does not "pass by
reference".


Arguments are always passed by value in C function calls, meaning that local copies of the values of the arguments are passed to the routines. Changes that you may make to the arguments in the function are made only to the local copies of the arguments. Passing by reference means you can change the value of the argument outside the scope of your function, which doesn't happen. If you have a function like: void foo(char *a) you cannot change the value of the argument, but you can change the content of the memory that the address points to. Pass-by-xxxx refers to the way the arguments are passed to the function and, in C, it's always by value. The fact that the function can change the value at the address your pointer points to is just a side-effect and has nothing to do with how the arguments are passed.

I don't remember exatly and I don't have a copy of the book right now, but I think K&R says that arguments are always passed by value in C function calls. No one will say anything about pass by reference because there's no such thing in C.

JAVA is a languae where everything's a reference. JAVA also passes the arguments to functions by value *only* (if you don't believe me check the documentation), but you can change the elements of an array that's passed to a function and it doesn't mean that array was passed by reference.

If I remember correctly in C++:

void foo(int &i) {
i=2;
}
....
int i=0;
foo(i)
=> i=2

type is int, you send int, int is changed in the function. That's pass by reference.

in C:

void foo(int *i) {
*i=2;
}
....
int i=0;
foo(&i);
=> i=2

type is int, you send a pointer to int, int is changed in the function. The functions doesn't tell you that it needs an int to change an int. It tells you it needs a pointer to int that it can't change.
Although you can consider &int a reference to an int, the function doesn't ask for a reference but for a type which is called "pointer to int" and what you send is the value of a pointer to int type.

--
Ioan - Ciprian Tandau
ta****@freeshell.org
Jan 8 '06 #81
Nelu wrote:
On 2006-01-08, Joseph Dionne <jd*****@hotmail.com> wrote:
It is just as amusing as you assertion, backed by no well known authority of
the c language specification, that c does not support pass by reference.

Your continued reference to 'object' during replies proves my assertions --
recent OOP development (decades ago implemented recent, I mean) have
obfuscated the meaning of "pass by reference". I suspect this is due mostly
to the declining software knowledge, and skills, that has again raised the
acclaim and praise for "garbage collection" languages.

Show me any authority that shares you "opinion" that c does not "pass by
reference".

Arguments are always passed by value in C function calls, meaning that local copies of the values of the arguments are passed to the routines. Changes that you may make to the arguments in the function are made only to the local copies of the arguments. Passing by reference means you can change the value of the argument outside the scope of your function, which doesn't happen. If you have a function like: void foo(char *a) you cannot change the value of the argument, but you can change the content of the memory that the address points to. Pass-by-xxxx refers to the way the arguments are passed to the function and, in C, it's always by value. The fact that the function can change the value at the address your pointer points to is just a side-effect and has nothing to do with how the arguments are passed.

I don't remember exatly and I don't have a copy of the book right now, but I think K&R says that arguments are always passed by value in C function calls. No one will say anything about pass by reference because there's no such thing in C.

JAVA is a languae where everything's a reference. JAVA also passes the arguments to functions by value *only* (if you don't believe me check the documentation), but you can change the elements of an array that's passed to a function and it doesn't mean that array was passed by reference.

If I remember correctly in C++:

void foo(int &i) {
i=2;
}
...
int i=0;
foo(i)
=> i=2

type is int, you send int, int is changed in the function. That's pass by reference.


It is pass by reference *because* i can and is modified. So to is i modified
in c, only the syntax has been changed to protect the innocent?
in C:

void foo(int *i) {
*i=2;
}
...
int i=0;
foo(&i);
=> i=2

type is int, you send a pointer to int, int is changed in the function. The functions doesn't tell you that it needs an int to change an int. It tells you it needs a pointer to int that it can't change.
Although you can consider &int a reference to an int, the function doesn't ask for a reference but for a type which is called "pointer to int" and what you send is the value of a pointer to int type.

Jan 8 '06 #82
On 2006-01-08, Nelu <ta****@freeshell.org> wrote:
<something about pass by reference>

Really sorry for the last post. I switched, recently,
from google groups to slrn and I didn't know it
knows not how to cut long lines. It's the first time
I use it...
I'll remember this for the future.
Also, from slrn it's easier to understand why keeping
some context when repying is useful :-).

--
Ioan - Ciprian Tandau
ta****@freeshell.org
Jan 8 '06 #83
On 2006-01-08, Joseph Dionne <jd*****@hotmail.com> wrote:
It is pass by reference *because* i can and is modified. So to is i modified
in c, only the syntax has been changed to protect the innocent?

In the C function I posted &i is the argument not i.
The i outside the function is modified but that i is not
the same as the one in the function. Modifying the i in the function
has no effect on the i outside the function. The i outside the function
is modified by modifying something different in the function,
i.e. *i which is not the variable you passed to the function.
Even if this is a mechanism that allows for the implementation of
pass-by-reference, it's not the same thing. You can say that
pass-by-reference can hide a pass-by-value but not that a pass-by-value
hides a pass-by-reference (otherwise it means that making a change
to the copy automatically changes the original, which doesnt't happen),
so they are not the same thing.
--
Ioan - Ciprian Tandau
ta****@freeshell.org
Jan 8 '06 #84
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Joseph Dionne wrote:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
No way! '&' is a bit wise logical AND, to get the contents of a
pointer, one codes it as "&pointer" not "& pointer" which will
generate an error.

Fortunately, the C language has rules that permit implementations to
distinguish between a "binary bitwise logical and" operator and a "unary
prefix address of" operator, even if they both share the same translation token.

Are you telling me that

{
int a = 7, b = 4, *c;

c = & a;
}

will result in a syntax error? I think not.
I'm beginning to suspect that you may be a deliberate troll. [snip] The unary "&" operator doesn't yield the contents of a pointer; it
yields the address of an object.
[snip]
It is just as amusing as you assertion, backed by no well known
authority of the c language specification, that c does not support pass
by reference.
- From the C 9989-1999 proposed standard (and, IIRC, from previous C standards,
all the way back to K&R C and forward to the accepted C'99 standard)

6.5.2.2 Function Calls

4 An argument may be an expression of any object type. In preparing for a
call to the function, the arguments are evaluated, and each parameter is
assigned the value of the corresponding argument.

Sounds like the standard says "pass by value" to me. And it doesn't say "pass
by reference" anywhere in it.

Perhaps you've become fooled by the mechanics of pointer variables. Passing
pointers to functions can /look/ like "pass by reference" even though it is
actually "pass by value". Consider the following code fragments

void foo(int *a)
{
/* body of function foo */
*a = 8;
}

void bar(void)
{
int q = 6;
foo(&q);
}

In the above functions, you might think that "pass by reference" is being
used, but it is not.

In the context of the function call to foo() ( "foo(&q);" )
q is an object of type int.

&q is another object (a temporary one crafted by the language to serve as a
vehicle to pass data to a function) of type "pointer to int"

q has a value of 6
&q has a value of a pointer to q

Function foo() will receive the /value/ of the temporary object &q. It does
not receive a /reference/ to q (or even to the temporary &q). It's as if that
original function had been coded as
void bar(void)
{
int q = 6;
int *pq = &q;

foo(pq); /* still pass by value, just value of pq */
}
Your continued reference to 'object' during replies proves my assertions
-- recent OOP development (decades ago implemented recent, I mean)
Well, Keith is using the word "object" in the same manner (and apparently with
the same meaning) as the C standard (and it's predecessor documents) does.

- From the C 9989-1999 proposed standard document section 3 ("Terms, definitions
and Symbols"):

3.14
object
region of data storage in the execution environment, the contents of which
can represent values

C 9989-1999 goes on using the word "object" throughout it's text, in exactly
the context that Keith has used it. I'm afraid that you don't have any choice
but to accept this terminology, recent OOP usage or not.
have
obfuscated the meaning of "pass by reference". I suspect this is due
mostly to the declining software knowledge, and skills, that has again
raised the acclaim and praise for "garbage collection" languages.

Show me any authority that shares you "opinion" that c does not "pass by
reference".


I think that the C standards should be sufficient authority to confirm Keith's
"opinion".

- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)

iD8DBQFDwKNjagVFX4UWr64RAvDrAJ9JRNN/WaXaq0J4O4egJiuRwCtNiQCeN/y5
ou4vGFXt3wBzmmUDCwCz/+I=
=p6kP
-----END PGP SIGNATURE-----
Jan 8 '06 #85
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nelu wrote:
On 2006-01-08, Joseph Dionne <jd*****@hotmail.com> wrote:
It is just as amusing as you assertion, backed by no well known authority of
the c language specification, that c does not support pass by reference.

Your continued reference to 'object' during replies proves my assertions --
recent OOP development (decades ago implemented recent, I mean) have
obfuscated the meaning of "pass by reference". I suspect this is due mostly
to the declining software knowledge, and skills, that has again raised the
acclaim and praise for "garbage collection" languages.

Show me any authority that shares you "opinion" that c does not "pass by
reference".

Arguments are always passed by value in C function calls, meaning that
local copies of the values of the arguments are passed to the routines.

[snip] I don't remember exatly and I don't have a copy of the book right now,
but I think K&R says that arguments are always passed by value in C function
calls. No one will say anything about pass by reference because there's no

such thing in C.

You are correct.

K&R C (First edition) says

"In preparing for the call to a function, a copy is made of each actual
parameter; thus, all argument-passing in C is strictly by value."

(Appendix A: C Reference Manual, "The C Programming Language", Brian W.
Kernighan & Dennis M. Ritchie, Copyright 1978 by Bell Telephone Laboratories,
Incorporated, Published by Prentice-Hall, Inc.)
[snip]

- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)

iD8DBQFDwKVVagVFX4UWr64RAv9TAKC564WPjQqJmYXWaCQkRp 3X3j3vCQCfXWPG
Jbi1XWwB3A3vCNa0SQTfGac=
=kjjN
-----END PGP SIGNATURE-----
Jan 8 '06 #86
Nelu wrote:
On 2006-01-08, Joseph Dionne <jd*****@hotmail.com> wrote:
It is pass by reference *because* i can and is modified. So to is i modified
in c, only the syntax has been changed to protect the innocent?


In the C function I posted &i is the argument not i.
The i outside the function is modified but that i is not
the same as the one in the function. Modifying the i in the function
has no effect on the i outside the function. The i outside the function
is modified by modifying something different in the function,
i.e. *i which is not the variable you passed to the function.
Even if this is a mechanism that allows for the implementation of
pass-by-reference, it's not the same thing. You can say that
pass-by-reference can hide a pass-by-value but not that a pass-by-value
hides a pass-by-reference (otherwise it means that making a change
to the copy automatically changes the original, which doesnt't happen),
so they are not the same thing.


The syntax difference in c++ is sexier, easier for those new to the language
to implement with less debug time, but is nothing more than using the
principle of passing a reference to a variable in order to modify the original
memory contents.

A custom c pre processor can simulate the same syntax, even support both
syntax, but that would most likely introduce more developer coding bugs not
less as desired.

I will only agree to disagree with the assertions made that "pass by
reference" is more about language syntax than language capability. Pass by
reference as a principle is well defined, and c complies with the definition.

Now this *troll* needs to get on with real world work, as some suggest I lack.

Cheers to all, the discussion was enlightening.
Jan 8 '06 #87
Joseph Dionne said:
A pointer can be passed by value,
Yes, I know. In fact, that is the only way it can be passed directly as a
function argument.
it that address of the memory storing an
address to memory used for "data", or passed by reference to "hide" it
memory address from the function called.
No, it can't be passed by reference.

For example, using your allocstr() function called by value;

{
char *t;

allocstr(t,10);
}

Will not have the desired result,
Gosh.
char pointer t will remain pointing at
it
original ram address both before and after the call to allocstr().
Is that right?
However, I can pass a reference to t, syntactically &s, that WILL have the
desired result.
No, you can't, because it's the wrong type, and in any case passing *a*
reference is not the same as passing *by* reference.

Note for terminology bigots: "The technical term used in programming
languags for an address of a location in memory is a /reference/ because it
/refers/ to a memory location." - Bruce Maclennan, "Principles of
Programming Languages", p57). The C Standard does not appear to use the
word in this way, however; at least, neither the C89 draft nor N869.
(Searching a PDF is like searching your spam for email, so I didn't look in
C99 Final.)

Further "by value" passing of pointers is strlen() implementation, for
example;

int strlen(char *s)
If that's how you implement strlen, remind me not to use your
implementation.
{
int ii;

for(ii=0;*s;ii++);


Undefined behaviour when (not if) ii overflows. It will overflow for all
strings except the empty string.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #88
Keith Thompson said:
Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct.
Right.
Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference.
To a newbie, the two statements can seem equivalent, especially if he
doesn't know what "pass by reference" is and has to go and look it up. Why
use the phrase at all, when it doesn't add any value?
Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.
We can ease that journey by not giving him useless junk to remember.
Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


I know what you're saying, but I think that's an own-foot-shooting way to
say it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #89
Joseph Dionne wrote:
[...]

Show me any authority that shares you "opinion" that c does not "pass by
reference".


"In preparing for the call to a function, a copy is made of each
argument; all argument-passing is strictly by value."
The C Programming Language, Second edition.
Brian W. Kernighan, Dennis M. Ritchie
A7.3.2 Function Calls (pages 201, 202)
Jan 8 '06 #90
Joe Wright said:
Jordan Abel wrote:
[...] time() takes its argument by reference [as do many other
functions in time.h, for historical reasons] You are conflating a
generic concept with a specific feature C++ has that C does not.


I may have to look this up because an exact example eludes me right now.


You needn't bother - Jordan is wrong about time() which does not in fact
take its argument by reference. It takes its parameter by value. The
argument is evaluated, and that value passed to time(). It's just like any
other parameter-taking C function in that regard.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #91
Joseph Dionne said:
No way! '&' is a bit wise logical AND, to get the contents of a pointer,
one codes it as "&pointer" not "& pointer" which will generate an error.


Case closed, I think, as far as Mr Dionne is concerned.

Troll, idiot, or newbie. In this case, I don't really see the point in
trying to distinguish between them.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #92
Joseph Dionne said:
Look who is being humorous. Sir, in you example, "buf" will never change
is
memory value, even *if* you pass it by reference, "& buf".


That isn't passing buf by reference. It's passing the address of buf by
value.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #93
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
[...]
No way! '&' is a bit wise logical AND, to get the contents of a
pointer, one codes it as "&pointer" not "& pointer" which will
generate an error.
[...] There are two "&" operators in C, a binary operator (taking two
operand) that performs a bitwise logical AND, and a unary operator
(taking one operand) that yields the address of its operand.
The expressions "&pointer" and "& pointer" are precisely equivalent.
The amount of whitespace between the operator and the operand is not
significant. The compiler is able to distinguish between unary and
binary "&" by the context in which it appears.
The unary "&" operator doesn't yield the contents of a pointer; it
yields the address of an object. [...] I suggest you read a good C textbook (K&R2 is very good). You have a
lot of things to unlearn.
(Or if you're doing this deliberately, please please please go away;
it's not amusing.)
It is just as amusing as you assertion, backed by no well known
authority of the c language specification, that c does not support
pass by reference.


I didn't say that C doesn't support pass by reference. I said that C
doesn't *directly* support pass by reference, but that a programmer
can *implement* pass by reference using the features of the language.
Your continued reference to 'object' during replies proves my assertions --
recent OOP development (decades ago implemented recent, I mean) have
obfuscated the meaning of "pass by reference". I suspect this is due
mostly to the declining software knowledge, and skills, that has again
raised the acclaim and praise for "garbage collection" languages.
What does my use of the term "object" have to do with anything? The C
standard defines an "object" as a "region of data storage in the
execution environment, the contents of which can represent values"
(C99 3.14). I wasn't using the term in the sense of object-oriented
programming. (The C++ standard's definition of "object" is similar.)
Show me any authority that shares you "opinion" that c does not "pass
by reference".


C99 6.5.2.2p4:

An argument may be an expression of any object type. In preparing
for the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument. 79)

Footnote 79:

A function may change the values of its parameters, but these
changes cannot affect the values of the arguments. On the other
hand, it is possible to pass a pointer to an object, and the
function may change the value of the object pointed to. A
parameter declared to have array or function type is adjusted to
have a pointer type as described in 6.9.1.

Which is what I've been saying all along.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #94
Richard Heathfield <in*****@invalid.invalid> writes:
Keith Thompson said:
Then we need to make it very clear to J Random Newbie that C doesn't
support pass by reference as a languag construct.


Right.
Don't say that the
"*" means pass by reference; say that the "*" means you're passing a
pointer value, which can be used to do the equivalent of pass by
reference.


To a newbie, the two statements can seem equivalent, especially if he
doesn't know what "pass by reference" is and has to go and look it up. Why
use the phrase at all, when it doesn't add any value?
Until J Random Newbie is able to hold that entire complex
thought in his head, he's not going to be able to be an effective C
programmer.


We can ease that journey by not giving him useless junk to remember.
Pass by reference is a very common and useful programming technique,
one that C supports quite well (though arguably a little more clumsily
than some other languages do).


I know what you're saying, but I think that's an own-foot-shooting way to
say it.


Ok, I see your point. I suppose it depends on the kind of newbie.

Personally, I learned Pascal before I learned C, so I already knew
about pass-by-value and pass-by-reference. From that perspective,
understanding that passing a pointer is the way to emulate
pass-by-reference in C was very important. Things might be different
for a non-programmer learning C.

On the other hand, I'm not sure that C is a good choice for a first
language. In any case, a programmer should *eventually* understand
the concepts of pass-by-value and pass-by-reference. And I tend to
think that it's at least as important to use C (or any language) as a
vehicle for learning about programming as it is to learn the details
of the language itself.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #95
On Sun, 08 Jan 2006 07:14:20 +0000, Keith Thompson wrote:
[...]
I didn't say that C doesn't support pass by reference. I said that C
doesn't *directly* support pass by reference, but that a programmer
can *implement* pass by reference using the features of the language.
[...] C99 6.5.2.2p4:

An argument may be an expression of any object type. In preparing
for the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument. 79)

Footnote 79:

A function may change the values of its parameters, but these
changes cannot affect the values of the arguments. On the other
hand, it is possible to pass a pointer to an object, and the
function may change the value of the object pointed to. A
parameter declared to have array or function type is adjusted to
have a pointer type as described in 6.9.1.

Which is what I've been saying all along.

- in both debates it's often argued that "C does not support the
concept directly, but supports its implementation trivially". In the case
of multi-dimensional arrays, the Standard contradicts this argument since
it explicitly describes a C array declared with more than one index as
multi-dimensional.

In the case of pass by reference, the opposite seems to be true: both
the Standard and its predecessor, K&R, explicitly describe C's parameter
passing as by value.

I think it's reasonable though to refer to C's simulation of this concept
as "pass by reference" (quote marks included) as a shortcut for a longer
expression similar to "pass the object's address to the function so that
the object's value may be modified", when it's clear that the writer is
not referring to the concept as supported more directly by languages like
C++ and Pascal.

--
http://members.dodo.com.au/~netocrat
Jan 8 '06 #96
On Sun, 08 Jan 2006 08:59:41 +0000, Netocrat wrote:
[slip-of-the-finger posted an article still being drafted; try again]
On Sun, 08 Jan 2006 07:14:20 +0000, Keith Thompson wrote:
[...]
I didn't say that C doesn't support pass by reference. I said that C
doesn't *directly* support pass by reference, but that a programmer can
*implement* pass by reference using the features of the language.


You've written something very similar in the past about multidimensional
arrays. On that occasion I disagreed because the Standard contradicts it.
On this occasion, I agree with your analysis as it seems to be supported
by both the Standard and K&R.

[omit wafflier wordage of draft post]

--
http://members.dodo.com.au/~netocrat

Jan 8 '06 #97
Nelu wrote:
.... snip ...
type is int, you send a pointer to int, int is changed in the function. The functions doesn't tell you that it needs an int to change an int. It tells you it needs a pointer to int that it can't change.
Although you can consider &int a reference to an int, the function doesn't ask for a reference but for a type which is called "pointer to int" and what you send is the value of a pointer to int type.


Please fix your right hand margin. Lines must never exceed 80
chars according to standards, and prefereably should not exceed
about 65 or so (to allow for quote marks).

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 8 '06 #98
Keith Thompson wrote:
.... snip ...
Personally, I learned Pascal before I learned C, so I already
knew about pass-by-value and pass-by-reference. From that
perspective, understanding that passing a pointer is the way to
emulate pass-by-reference in C was very important. Things might
be different for a non-programmer learning C.

On the other hand, I'm not sure that C is a good choice for a
first language. In any case, a programmer should *eventually*
understand the concepts of pass-by-value and pass-by-reference.
And I tend to think that it's at least as important to use C (or
any language) as a vehicle for learning about programming as it
is to learn the details of the language itself.


Fortunately for JRN the use of pass-by-name has virtually
disappeared. In fact fortunately for most of us, IMO.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Jan 8 '06 #99
On 2006-01-08, Richard Heathfield <in*****@invalid.invalid> wrote:
Joe Wright said:
Jordan Abel wrote:
[...] time() takes its argument by reference [as do many other
functions in time.h, for historical reasons] You are conflating a
generic concept with a specific feature C++ has that C does not.
I may have to look this up because an exact example eludes me right now.


You needn't bother - Jordan is wrong about time() which does not in fact
take its argument by reference. It takes its parameter by value.


It takes a time_t by reference. You are once again refusing to recognize
the existence of the programming technique called "pass by reference" -
if someone started talking about linked lists in here, you wouldn't
object that C doesn't support those, despite the fact that they (unlike
pass by reference) are not used at all by the interface to the standard
library.
The argument is evaluated, and that value passed to time(). It's just
like any other parameter-taking C function in that regard.

Jan 8 '06 #100

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

699
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
18
by: Minti | last post by:
I was reading some text and I came across the following snippet switch('5') { int x = 123; case '5': printf("The value of x %d\n", x); break; }
6
by: Code Raptor | last post by:
Folks, I am hitting a segfault while free()ing allocated memory - to make it short, I have a linked list, which I try to free node-by-node. While free()ing the 28th node (of total 40), I hit a...
12
by: G Patel | last post by:
I've seen some code with extern modifiers in front of variables declared inside blocks. Are these purely definitions (no definition) or are they definitions with static duration but external...
7
by: seamoon | last post by:
Hi, I'm doing a simple compiler with C as a target language. My language uses the possibility to declare variables anywhere in a block with scope to the end of the block. As I remembered it this...
7
by: BT | last post by:
Ok, for a school assignment we have to use a pointer for an array of ints, intstead of the usual X way, it compiles fine but when i run it I am getting a seg fault that i can't figure out how to...
8
by: nobrow | last post by:
Okay ... Im out of practice. Is it not possible to have a 2D array where each column is of a different type, say an int and a struct*? The following seg faults for me and I cant figure out what I...
24
by: Neal Becker | last post by:
One thing I sometimes miss, which is common in some other languages (c++), is idea of block scope. It would be useful to have variables that did not outlive their block, primarily to avoid name...
10
by: somebody | last post by:
There are two files below named search.c and search.h. In the for loop in search.c, the for loop never exits, even if mystruct.field1 has no match. Instead of exiting the for loop it keeps going...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.