Re: why cannot assign to function call
- From: Mark Wooding <mdw@xxxxxxxxxxxxxxxx>
- Date: Sun, 11 Jan 2009 10:47:09 +0000 (UTC)
rurpy@xxxxxxxxx <rurpy@xxxxxxxxx> wrote:
Mark Wooding wrote:
rurpy@xxxxxxxxx <rurpy@xxxxxxxxx> wrote:
What is the observable difference between converting an
array to a reference (pointer) to that array and passing
the reference by value, and passing the array by reference?
For one:
#include <stdio.h>
static size_t foo(char v[]) { return sizeof v; }
int main(void) {
char v[sizeof(char *) * 10];
puts(foo(v) == sizeof(char *) ? "pointer" : "reference");
return (0);
}
You are saying that because the size of the argument
(10) is not available in the function, it cannot be
call-by-reference?
No, I'm saying that because the parameter has pointer type, not array
type, it's a pointer being passed by value, not an array being passed by
reference.
And the size of the argument is not 10: it's 10 times as much as the
(nonzero) size of a pointer -- and therefore distinguishable on any C
implementation.
I think fortran is accepted as the archetypal call-by-
reference language and it does not automatically
supply argument size information to functions.
Well and dandy; but Fortran doesn't turn arrays into pointers.
For another:
static void bar(char v[]) { char ch = 0; v = &ch; }
/* type error if arrays truly passed by reference */
v can be used as an array reference, e.g. "v[1] = 23"
exactly as in the pass-by-reference fortran example. And
v can also be used as a local variable and reassigned.
If the first option was the only one, would you not
say C was definitely pass-by-reference (for arrays)?
If one could only use v as a pointer (i.e. access
the argument array as "*(v+1) = 23", then I would
say that arrays are not passed at all, only pointers
by-value.
Your knowledge of C is clearly limited, at best. The notations *(p + i)
and p[i] are entirely equivalent in every way, since the square-brackets
indexing operator is in fact defined in terms of pointer dereference
(6.5.2.1):
: [#2] 2 A postfix expression followed by an expression in square
: brackets [] is a subscripted designation of an element of an array
: object. The definition of the subscript operator [] is that E1[E2] is
: identical to (*((E1)+(E2))). Because of the conversion rules that
: apply to the binary + operator, if E1 is an array object
: (equivalently, a pointer to the initial element of an array object)
: and E2 is an integer, E1[E2] designates the E2-th element of E1
: (counting from zero).
Of course, because the + operator is commutative
That both these options exist causes me to conclude
that, for arrays, parameter passing can be viewed
as either arrays by-reference or pointers by-value.
I don't understand what relevance type checking
has. Since you are choosing to use v as a pointer,
one would not expect a type error, yes?
Compare:
void mumble(void) { char v[42]; char ch = 0; v = &ch; }
/* error: incompatible types in assignment */
It's because in the previous case v is a pointer that the compiler
doesn't mind me assigning to it. In this case, because it's an array,
the compiler objects.
I guess the case for pass-by-value would be a little stronger because
one has to have "passing a pointer by value" anyway (since pointers
are first-class datatypes) and that can be used to describe passing
arrays (as you described).
The difference is that the /callee/ function is different between the
two cases.
Also, notice that arrays in expressions turn into pointers in the same
way, so function argument passing works the same way as assignment -- a
hallmark of pass-by-value.
Not in all expressions as you yourself mentioned:
int a[10], *ap;
sizeof a;
sizeof ap;
Well done, you've pedantically picked up on the lapse in the first part
of the sentence (about sizeof, which as you say I've already mentioned
elsewhere) but failed to take any notice of the more important and
relevant point in the second half -- that argument passing works the
same way as assignment -- for `arrays' just as for other types.
void fa(char p[]);
void fp(char *p);
void fi(int i);
char a[10 * sizeof(char *)] = "bar", aa[10 * sizeof(char *)] = "splat";
char *p = "foo", *pp = "mumble";
int i = 42, ii = 69;
i = ii; /* assignment of integers */
fi(ii); /* integer call-by-value */
p = pp; /* assignment of pointers */
fp(pp); /* pointer call-by-value */
fa(pp); /* pointer call-by-value again */
a = aa; /* type error: incompatible types in assignment */
a = pp; /* type error: incompatible types in assignment */
p = aa; /* assignment of pointers */
fa(aa); /* pointer call-by-value yet again */
fp(aa); /* pointer call-by-value yet again */
Again, I refer readers to ISO 9899:1999: in particular:
* 6.3.2.1p3 (array-to-pointer decay)
* 6.5.2.2 (function calls)
* 6.5.16 (assignment operator)
Since I'm getting thoroughly fed up of repeating myself on this point,
I'm simply going to assume, from now on, that anyone who offers a
disagreement without citing passages from (at least a specific draft of)
ISO 9899 to support any claims made is simply being wilfully ignorant --
and therefore no longer worth my attention.
(If you don't have a copy of any such version, may I suggest
http://std.dkuug.dk/jtc1/sc22/open/n2794/
citing this (confusingly) as n843, as a place to start.)
-- [mdw]
.
- Follow-Ups:
- Re: why cannot assign to function call
- From: rurpy
- Re: why cannot assign to function call
- References:
- Re: why cannot assign to function call
- From: Steven D'Aprano
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: Aaron Brady
- Re: why cannot assign to function call
- From: Steven D'Aprano
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: Steven D'Aprano
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: Steven D'Aprano
- Re: why cannot assign to function call
- From: Aaron Brady
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: rurpy
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: rurpy
- Re: why cannot assign to function call
- From: Mark Wooding
- Re: why cannot assign to function call
- From: rurpy
- Re: why cannot assign to function call
- Prev by Date: Re: Python strings and coding conventions
- Next by Date: Re: Bad hack fix around a bizarre problem...
- Previous by thread: Re: why cannot assign to function call
- Next by thread: Re: why cannot assign to function call
- Index(es):
Relevant Pages
|