Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > scope of function parameters

Reply
Thread Tools

scope of function parameters

 
 
BartC
Guest
Posts: n/a
 
      02-07-2013


"Ben Bacarisse" <(E-Mail Removed)> wrote in message
news:0.b9e01566193df7c3d715.20130207220249GMT.8762 (E-Mail Removed)...
> "BartC" <(E-Mail Removed)> writes:


>> void iadd(int a[],int b) {

>
> There's no array here. I agree that it's confusing to people learning
> C, but the confusing thing is that 'a' is not an array. It's the fact
> that an array is *not* involved that is confusing.


What gets passed is a pointer to an int; you're right there's no array
involved. But in that case, what's going on here:

>> a[0]+=b;


Is this array subscripting, or just updating a pointer target?

How about this example:

int main(int argc, char *argv[]) ...

Here, argv is presumably a pointer to pointer to char; no array in sight
here either (other than the suspiciously array-like "[]" syntax!).

Yet a few lines further on in my C standard, it talks about "...the array
members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!

--
Bartc
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      02-07-2013
On 02/07/2013 05:37 PM, BartC wrote:
>
>
> "Ben Bacarisse" <(E-Mail Removed)> wrote in message
> news:0.b9e01566193df7c3d715.20130207220249GMT.8762 (E-Mail Removed)...
>> "BartC" <(E-Mail Removed)> writes:

>
>>> void iadd(int a[],int b) {

>>
>> There's no array here. I agree that it's confusing to people learning
>> C, but the confusing thing is that 'a' is not an array. It's the fact
>> that an array is *not* involved that is confusing.

>
> What gets passed is a pointer to an int; you're right there's no array
> involved. But in that case, what's going on here:
>
>>> a[0]+=b;

>
> Is this array subscripting, or just updating a pointer target?


The latter; a[0] += b is, by definition, equivalent to

*(a+0) = *(a+0) + b;

> How about this example:
>
> int main(int argc, char *argv[]) ...
>
> Here, argv is presumably a pointer to pointer to char; no array in sight
> here either (other than the suspiciously array-like "[]" syntax!).
>
> Yet a few lines further on in my C standard, it talks about "...the array
> members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!


The array whose first member is pointed at by argv. argv is not an
array, but there is one that it points into.

An lvalue of array type is, in most contexts, automatically converted to
a pointer to the first element of an array (sizeof and & are the two
relevant exceptions). As as a result, in precisely those same contexts,
a pointer to the first element of an array can be used just as if it
were an array.

 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      02-07-2013
"James Kuyper" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 02/07/2013 05:37 PM, BartC wrote:


>> int main(int argc, char *argv[]) ...
>>
>> Here, argv is presumably a pointer to pointer to char; no array in sight
>> here either (other than the suspiciously array-like "[]" syntax!).
>>
>> Yet a few lines further on in my C standard, it talks about "...the array
>> members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!

>
> The array whose first member is pointed at by argv. argv is not an
> array, but there is one that it points into.


It that just an *assumption* (that argv does in fact point to an array, and
not perhaps a struct with argc members), or is main() a special case, where
it is *known* that argv points to the start of an array? (Despite being
pretty much the only function where you can't know!)

If any pointer passed to a function might be assumed to point to the start
of an array, then it seems to me that you can also assume that a reference
to that array has been passed.

--
Bartc

 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      02-07-2013
On 2/7/2013 15:28, BartC wrote:
> "Shao Miller" <(E-Mail Removed)> wrote in message
> news:kerts4$1hk$(E-Mail Removed)...
>> On 2/5/2013 04:09, Esash wrote:

>
>>> I got confused with passing by value and passing by reference. Can
>>> anyone please clarify ?

>
>> The two are _separate_. The called function can modify its parameters
>> and those modifications _do_not_ modify the caller's arguments.
>> ... As another example:
>>
>> void bar(void) {
>> int i = 21;
>> int j = 21;
>> int x = add(i, j);
>> }
>>
>> Your 'add' function above cannot modify the arguments 'i' and 'j'. It
>> can only modify its parameters 'a' and 'b'.

>
> It gets a bit more confusing when arrays are involved:
>
> void iadd(int a[],int b) {
> a[0]+=b;
> }
>


I think you meant "It gets a bit more confusing when parameter
declarations appear to declare arrays". For a beginner, one of the
hurdles in C is that array declarators for function parameters actually
declare pointers. For this reason, I recommend avoiding array
declarators in function parameters altogether, unless one requires the
>= C99 conveniences (like 'static'), in which case one is probably not

a beginner to C.

> int main (void) {
> int x[]={10,20,30};
>
> iadd (x,1);
> }
>
> Here, the caller's 'x' argument *is* apparently modified. In fact, an
> array can *only* be passed by reference.
>


Well that might add to the confusion. In 'main', the 'x' array object
isn't an argument, and 'iadd' doesn't modify its arguments (nor does any
C function access its caller's arguments). One thing that can be said
is that the 'x' lvalue is not the same as the value of the expression
'x'. Lvalue conversion and "array decay" are side-by-side concepts that
can be challenging for a beginner to grasp, but the sooner done, the better.

I like to imagine an "evaluation pass". Given (in a function):

int x[] = { 10, 20, 30 };
int y = 13;
int z = 42;

foo(x, y, z, bar());

I imagine an "evaluation pass" resulting in:

foo(pointer to first element of x, 13, 42, result of call to bar);

These more accurately describe the arguments to 'foo'. We can see that
all of the originals are, after some evaluation has happened, _not_
arguments to 'foo'. In normal discussion, we might say that they are,
but this can contribute to beginners' confusion.

There is another confusing case that's similar to "array decay", and
that's "function decay", which explains the difference between these two
lines:

int sz = sizeof main;
int sz = sizeof (0, main);

In the latter, 'main' "decays" to a function pointer, just as array
expressions decay to object pointers. And, just like array expressions,
this same decay happens when 'main' appears to be an argument in a
function call. There is again a similar relationship to arrays for
function parameters: A function parameter declarator that itself appears
to declare a function actually declares a function pointer parameter.

I seem to recall another comp.lang.c post referencing "Haddocks' Eyes":

http://en.wikipedia.org/wiki/Haddocks%27_Eyes#Naming

The argument is called 'x', but the argument is a pointer to the first
element of 'x'.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-07-2013
On 02/07/2013 06:05 PM, BartC wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On 02/07/2013 05:37 PM, BartC wrote:

>
>>> int main(int argc, char *argv[]) ...
>>>
>>> Here, argv is presumably a pointer to pointer to char; no array in sight
>>> here either (other than the suspiciously array-like "[]" syntax!).
>>>
>>> Yet a few lines further on in my C standard, it talks about "...the array
>>> members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!

>>
>> The array whose first member is pointed at by argv. argv is not an
>> array, but there is one that it points into.

>
> It that just an *assumption* (that argv does in fact point to an array, and
> not perhaps a struct with argc members), or is main() a special case, where
> it is *known* that argv points to the start of an array?


The standard requires that the implementation do whatever it needs to do
to make argv[i] work, as described by the standard, for any value of i
from 0 to argc, inclusive. If the code that calls main() were strictly
conforming C code, that would be pretty closely equivalent to requiring
that argv point into an array - though it need not point to the first
element of that array, and argv+argc need not point at the last element
of that array. In that case, if argc == 0, then argv could point at a
single char* object, which the standard allows to be treated as an array
of length one. I can't come up with any plausible reason for an
implementation to do that, but it would be permitted.

However, the standard doesn't even require that the caller of main be
written in C code, much less strictly conforming C code, so there's no
way to even make the question meaningful. However, what it does say is,
for all practical purposes (such as understanding how to use argv, or
how to write recursive calls to main()), equivalent to requiring that
argv point into an array.

....
> If any pointer passed to a function might be assumed to point to the start
> of an array, then it seems to me that you can also assume that a reference
> to that array has been passed.


Since C doesn't define any mechanism whereby a reference to an array
could be passed to a function, that assumption would lead to the
conclusion that the program has undefined behavior. That doesn't seem
like a useful assumption to make.

 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      02-07-2013
On 2/7/2013 18:05, BartC wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On 02/07/2013 05:37 PM, BartC wrote:

>
>>> int main(int argc, char *argv[]) ...
>>>


I'd suggest avoiding that and using:

int main(int argc, char ** argv)

>>> Here, argv is presumably a pointer to pointer to char; no array in sight
>>> here either (other than the suspiciously array-like "[]" syntax!).
>>>
>>> Yet a few lines further on in my C standard, it talks about "...the
>>> array
>>> members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!

>>
>> The array whose first member is pointed at by argv. argv is not an
>> array, but there is one that it points into.

>
> It that just an *assumption* (that argv does in fact point to an array,
> and not perhaps a struct with argc members), or is main() a special
> case, where it is *known* that argv points to the start of an array?
> (Despite being pretty much the only function where you can't know!)
>


In a hosted environment, the 'main' parameter 'argv' has to point into
an array. Why? Because of the second bullet of 5.1.2.2.1p2.

> If any pointer passed to a function might be assumed to point to the
> start of an array, then it seems to me that you can also assume that a
> reference to that array has been passed.
>


1. Pointers can point to functions, to no object, or to an incomplete
object type, besides arrays.

2. If you pass an 'int *', it is not a reference to an array. Why?
Because you cannot determine the array's size in any standard way,
whereas with an 'int (*)[10]', you can, and it _does_ provide a
reference to an array.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-08-2013
"BartC" <(E-Mail Removed)> writes:
> "Ben Bacarisse" <(E-Mail Removed)> wrote in message
> news:0.b9e01566193df7c3d715.20130207220249GMT.8762 (E-Mail Removed)...
>> "BartC" <(E-Mail Removed)> writes:
>>> void iadd(int a[],int b) {

>>
>> There's no array here. I agree that it's confusing to people learning
>> C, but the confusing thing is that 'a' is not an array. It's the fact
>> that an array is *not* involved that is confusing.

>
> What gets passed is a pointer to an int; you're right there's no array
> involved. But in that case, what's going on here:
>
>>> a[0]+=b;

>
> Is this array subscripting, or just updating a pointer target?


The subscript operator [] takes two operands, one of integer type and
one of pointer type. For the evaluation to be defined, the pointer
operand must point to an element of an array object. (A singleton
object is treated as a one-element array for this purpose).

> How about this example:
>
> int main(int argc, char *argv[]) ...
>
> Here, argv is presumably a pointer to pointer to char; no array in sight
> here either (other than the suspiciously array-like "[]" syntax!).


Yes, as a parameter declaration "char *argv[]" is exactly equivalent to
"char **argv" (and I personally prefer the latter).

> Yet a few lines further on in my C standard, it talks about "...the array
> members argv[0] through argv[argc-1]..." (5.1.2.2.2). What array?!


The anonymous array *object* created by the runtime environment before
invoking your main function. The implementation arranges for argv to
point to the first element of that array object.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-08-2013
"BartC" <(E-Mail Removed)> writes:

> "Ben Bacarisse" <(E-Mail Removed)> wrote in message
> news:0.b9e01566193df7c3d715.20130207220249GMT.8762 (E-Mail Removed)...
>> "BartC" <(E-Mail Removed)> writes:

>
>>> void iadd(int a[],int b) {

>>
>> There's no array here. I agree that it's confusing to people learning
>> C, but the confusing thing is that 'a' is not an array. It's the fact
>> that an array is *not* involved that is confusing.

>
> What gets passed is a pointer to an int; you're right there's no array
> involved. But in that case, what's going on here:
>
> Is this array subscripting, or just updating a pointer target?
>
>>> a[0]+=b;


Whatever you decide to call it, an array need not be involved. I can
call iadd like this:

int x;
iadd(&x, 42);

and a[0] += b; workds just fine. No array in sight.

> How about this example:
>
> int main(int argc, char *argv[]) ...
>
> Here, argv is presumably a pointer to pointer to char; no array in
> sight here either (other than the suspiciously array-like "[]"
> syntax!).
>
> Yet a few lines further on in my C standard, it talks about "...the
> array members argv[0] through argv[argc-1]..." (5.1.2.2.2). What
> array?!


There is an array involved here -- the standard says so. It may have
only one element (and therefore be very like a single object) but there
is an array of char pointers.

When you see only the parameter declared like this: T p[], you don't
know if there is an array anywhere in the program so you can't tell from
looking at the declaration of main alone if there is one or not, but the
standard clears it by telling you that what will be passed is a pointer
to the first element of an array.

Obviously, the pointer that is assigned to a parameter declared with the
[] syntax will often be to the start of an array, and it is perfectly
reasonable to talk, in general, about indexing (the other []s) as being
"an array access", but saying that arrays "are passed by reference" is
just wrong and confusing. The treatment of arrays is special in far
more situations that simple parameter passing, and C does not have "pass
by reference" for any types.

--
Ben.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      02-08-2013
On 2/7/2013 7:25 PM, Keith Thompson wrote:
>
> The subscript operator [] takes two operands, one of integer type and
> one of pointer type. For the evaluation to be defined, the pointer
> operand must point to an element of an array object. [...]


Nitpick: "... or must point one element-worth beyond the
last element of an array object." (In this case, the integer
operand would necessarily be negative.)

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
scope of function parameters Henry Olders Python 21 05-31-2011 05:33 PM
Re: scope of function parameters (take two) Henry Olders Python 2 05-31-2011 05:03 AM
Re: scope of function parameters Wolfgang Rohdewald Python 8 05-29-2011 07:20 PM
Having trouble understanding function scope and variable scope Andrew Falanga Javascript 2 11-22-2008 09:23 PM
Class Member Data and Member Function Parameters - Should Parameters Be Data Members? Jason C++ 2 05-13-2006 07:11 AM



Advertisments