Link to home
Start Free TrialLog in
Avatar of jtcy
jtcy

asked on

Parameter Passings

Can someone explain to me about these? I am kind of confused with these different types of passing parameters. These are what i thought...

Call-By-Value

public int getSum(int n)
{
   int i = n;
   i++;
   return i;
}

// so obviously formal parameter is assigned to be a local variable (is this the right way of saying?) and actual parameter is never changed.


Call-By-Result

public int getSum(int n)
{
   i++;
   n = i;
   return n;
}

//I donno if this is correct...So actual parameter get changed??


Call-By-Result-Value

public int getSum(int n)
{
   int i = n;
   i++;
   n = i;
   return n;
}


// is this correct????



Call-By-Name

Now what is this call-by-name thing???



Also, for Call-By-Reference, to pass an array, do we do like this?

a[1] = 'a';
int *p = &a[0];
getSum(p); //is this the correct way?? Does it mean just passing the address of the first element in?
getSum(a); //what about this? does this mean passing the whole array into the function? or the first element only?

public int getSum(int *n)
{
   int sum = 0;
   sum = sum + n;
   n++; //does this work? since n is a pointer...i tot it would~  
}



SOLUTION
Avatar of brunomsilva
brunomsilva

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of snehanshu
snehanshu

brettmjohnson,
>>Complex data types are arrays, structures, and unions.  ANSI-C implicitly passes all complex data types by reference.
Aren't structures and unions passed by value?
...Snehanshu
> Aren't structures and unions passed by value?

Not in ANSI C.  The called routine gets a pointer to the structure.

brettmjohnson,
For this code:
#include <stdio.h>

struct mystruct
{
  int a;
};

int mytest(mystruct mytmp)
{
  mytmp.a *= 10;
  printf("%d\n", mytmp.a);
  return mytmp.a;
}

int main()
{
  mystruct myvar;
  myvar.a = 10;
  printf("%d\n", myvar.a);
  mytest(myvar);
  printf("%d\n", myvar.a);
  return 0;
}

Which C compiler produces the output
10
100
100
because that should happen if address of structure is passed. I get
10
100
10
in visual studio 2002 .net (after a few tweaks).
Also I couldn't find any mention of structures being passed as addresses in ISO/IEC 9899 (ANSI C standard). It talks only about arays.
6.5.2.2: Function calls note 78 and 6.9.1
...Snehanshu
i agree with snehanshu, structures are passed by value,..arrays  by the address..
if strucures were passed by address by default, then u wouldnt see standard library functions using pointers to structures...and i feel its understood here whats the cost of letting the structures passed by value.
akshay
jtcy,
  A small correction in my earlier explanation of your Call-By-Result (As pointed out by  brunomsilva and brettmjohnson):
I wrote:
>>So, if you call getSum as
>>int myretval, myparam;
>>myparam = 40;
>>myretval = getSum(myparam)
>>then myparam remains unchanged, but myretval becomes 41.

Well, I had not noticed that yoi haven't defined i in getSum. So, if i is a global variable then the explanation would be

If you call getSum as
int myretval, myparam;
i = 40; //assuming i is declared outside main
myretval = getSum(myparam)
then myparam remains unchanged, but myretval becomes 41.

And a reminder: Please keep closing your questions if you expect to get promptly answered :-)

Cheers!
...Snehanshu
snehanshu,

I stand corrected.  pre-ANSI C did not specify passing structures by value (although
some compilers supported it, most didn't).
But ANSI-C does specify passing and returning structures by value (Sec. 2.2.3 p. 13).

When I think back 15 years ago I vaguely remember this.  Early compilers (Lattice C?)
would implicitly pass structures by reference. However, as the ANSI spec started to
come together, they started throwing a warning at the construct.  The compiler still
didn't support passing structures, but they would throw a warning when doing the
implicit pointer conversion.  I guess I'm so old that I never considered passing structs
by value.  When I think back, there was probably one or two occasions where passing
structs by value would have been useful.


brettmjohnson,
  It feels great to know I am young in this big bad world :-) Working on C 15 years ago sounds so exciting!
  It seems that lately, Akshay and I have somehow taken up the task of posting our views on every comment that has any thing to do with passing parameters: no offence meant.
  Cheers,
...Snehanshu
P.S.
  It seems we have different ANSI-C manuals: the PDF I downloaded yesterday doesn't have a Sec. 2.2.3 p. 13, but I guess it doesn't matter as long as we all agree :-)
Avatar of Kent Olsen

It was just a couple of weeks ago that I made the concensus argument regarding passing by value vs passing by reference and ganged up on by theorists claiming that C didn't pass by reference.  (Their argument seemed to be that placing the address of an object on the stack was really passing by value since an address is a value.)  They even argued that K&R made that claim so it must be right....

Where were you guys???    :)

Kent
>> Where were you guys???
Dear Sir,
I have no clue of what's being talked about.
"Take it to the lounge" and post a link (to the lounge question) here.
...Shu
In case jtcy's silence is confusion (rather than loss of interest), the following illustrates how arrays are passed by reference and structs are passed by value (i.e. as copies). See how pointers aren't used in this.

--------8<--------
#include <stdio.h>

int x[1];
struct X {int x;} s;

void poke_array(int[1]);
void poke_struct(struct X);

int main()
{
        x[0] = 99;
        printf("x[0] = %d\n",x[0]);
        poke_array(x);
        printf("x[0] = %d\n",x[0]);

        printf("\n");

        s.x = 77;
        printf("s.x = %d\n",s.x);
        poke_struct(s);
        printf("s.x = %d\n",s.x);
}

void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",ref[0]);
        ref[0] = 66;
        printf("ref[0] = %d\n",ref[0]);
}

void poke_struct(struct X cpy)
{
        printf("cpy.x = %d\n",cpy.x);
        cpy.x = 44;
        printf("cpy.x = %d\n",cpy.x);
}
--------8<--------

You're probably thinking that the reference is really a pointer in C and if you rewrite poke_array as follows, you'll see that you are right:
--------8<--------
void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",*ref); /* A pointer?! */
        *ref = 66;
        printf("ref[0] = %d\n",*ref);
}
--------8<--------

You'll find that you can treat ref just like a pointer and (ignoring the fact that we are incrementing beyond the bounds of our array), you'll find that the following compiles OK in C or C++, though it should look very wrong to you:
--------8<--------
void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",*ref); /* A pointer?! */
        *++ref = 66; /* Pre-increment and assign, just as if it was a pointer */
        printf("ref[1] = %d\n",*ref);
}
--------8<--------

Lo and behoold, we can treat the reference to the array just as though it was a pointer. You may as well admit to the fact that your reference is a pointer and prototype it thus:
--------8<--------
void poke_array(int* ref);
--------8<--------

Why then, can't you compile the following code, you might ask yourself:
--------8<--------
int main()
{
    int x[2];
    *++x = 2;
}
--------8<--------

The reason that this doesn't work is that the compiler hasn't stored the address of the array in a variable anywhere (we're not working with a reference) and therefore it is unable to increment a pointer.

Silly language, isn't it?
Hi jtcy!

After tons of C-specific pitfalls: Call-by-name is a construct from languages like perl or ruby, where you can explicitly state which parameter you'll set with the following value, like in Perl:

create_human(height=>6,weight=>140,sex=>"M",name=>"Adam");

All other possible parameters have default values. This is basically passing a hash of name/value pairs.

This is for sure possible to implement in C++ (or even C), but the code will look messy.
If the asker is not interested, I am not interested either.
PAQ the question without refunding points as far as I am concerned.
thanks,
...Shu