# Re: pointers...

Discussion in 'C Programming' started by Rob, Jun 25, 2003.

1. ### RobGuest

"geo" <geometrikal@hhoottmmaaiill> wrote in message
news:...
> hi all
> Whole question snipped. Essentially asking "is it best to pass a struct

by value, or by
> passing the address as a pointer, to a function?"

If the function is required to update the struct on behalf, and have those
changes seen by the
caller, then passing a pointer is obviously best.

If the function may update the structure, but the caller doesn't want to be
affected by those
changes, then passing by value is best.

Other arguments usually come down to some measure of performance, and amount
to the
comparison of the cost (eg machine cycles, memory usage) of actually calling
the function.
Let's say, for example, that we're operating on a 32 bit machine, and
pointers are represented
in 32 bits (i.e. 4 8-bit bytes). Passing anything by value amounts to
passing a copy of the
original, meaning the copy has to be created. As a rough rule of thumb,
copying a big struct
will cost more (time, memory usage, etc)than passing a small struct or a
pointer. So, if
the struct is suitably small, passing by value will be less costly than
passing a pointer (which
actually passes the pointer by value). Passing a larger struct will be
more costly than passing
it's address. The problem is that the transition (to where it costs less
of a copy of the struct) depends on many things, such as compiler
optimisation and system
architecture.
--

Rob, Jun 25, 2003

2. ### Rahul AgarkarGuest

The basic difference between the two methods is the way the struct is
being passed to the function. When you say

void function (struct struct_random r)

the structure is passed through pass by value method. In this, the
function will create a local copy of the structure and do the desired
operations.

In the other definition

void function (struct struct_random *r)
or
void function (const struct struct_random *r)

the structure is being passed by the pass by reference method. In this
method, a pointer to the structure is passed to the function. In the
former method, the original copy of the structure will be modified
inside the function where as the later one protects the original copy
from being modified.

Looking at the above scenarios, it is quite clear that there is no
definite answer to your question as which method is best. It all

I will give a few scenarios below where each of the above methods are
given :
In all these examples, assume there is a structure of an employee.

Scenario 1) The application wants to query the employee information or
perform some calculations which should not affect the original records
(for example, calculating the salaries of all the employees. In this
example, the application just reads the salary of each and every
employee and adds it up to the total salary). Also assume, there is
enough memory available on the machine where the application is
running. In this scenario, one can use following method :

void function (struct struct_random r)
{
total += r.salary; //total is some variable defined globally.
...
}

Scenario 2) The application needs to modify the salary of an
individual employee. Following method will be suitable :

void function (struct struct_random *r)
{
r->salary = 1000;
...
}

Scenario 3) Consider the scenario 1 again. The only changed condition
is you want to use less memory. This can be done by avoiding the extra
copies of the struct struct_random in the memory. This method will be
suitable for the purpose :

void function (const struct struct_random *r)
{
...
}

Please correct me if i am wrong...

- Rahul

"Rob" <> wrote in message news:<>...
> "geo" <geometrikal@hhoottmmaaiill> wrote in message
> news:...
> > hi all
> > Whole question snipped. Essentially asking "is it best to pass a struct

> by value, or by
> > passing the address as a pointer, to a function?"

>
>
> If the function is required to update the struct on behalf, and have those
> changes seen by the
> caller, then passing a pointer is obviously best.
>
> If the function may update the structure, but the caller doesn't want to be
> affected by those
> changes, then passing by value is best.
>
> Other arguments usually come down to some measure of performance, and amount
> to the
> comparison of the cost (eg machine cycles, memory usage) of actually calling
> the function.
> Let's say, for example, that we're operating on a 32 bit machine, and
> pointers are represented
> in 32 bits (i.e. 4 8-bit bytes). Passing anything by value amounts to
> passing a copy of the
> original, meaning the copy has to be created. As a rough rule of thumb,
> copying a big struct
> will cost more (time, memory usage, etc)than passing a small struct or a
> pointer. So, if
> the struct is suitably small, passing by value will be less costly than
> passing a pointer (which
> actually passes the pointer by value). Passing a larger struct will be
> more costly than passing
> it's address. The problem is that the transition (to where it costs less
> to pass a pointer instead
> of a copy of the struct) depends on many things, such as compiler
> optimisation and system
> architecture.

--

Rahul Agarkar, Jun 26, 2003

3. ### Richard HeathfieldGuest

Rahul Agarkar wrote:
>
> The basic difference between the two methods is the way the struct is
> being passed to the function. When you say
>
> void function (struct struct_random r)
>
> the structure is passed through pass by value method.

Obviously. All objects are passed by value in C.

> In this, the
> function will create a local copy of the structure and do the desired
> operations.

Right.

>
> In the other definition
>
> void function (struct struct_random *r)
> or
> void function (const struct struct_random *r)
>
> the structure is being passed by the pass by reference method.

No, it isn't. A pointer to the structure is being passed, by value.

<snip>

--
Richard Heathfield :
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Richard Heathfield, Jun 26, 2003
4. ### Richard HeathfieldGuest

Rahul Agarkar wrote:
>
> The basic difference between the two methods is the way the struct is
> being passed to the function. When you say
>
> void function (struct struct_random r)
>
> the structure is passed through pass by value method.

Obviously. All objects are passed by value in C.

> In this, the
> function will create a local copy of the structure and do the desired
> operations.

Right.

>
> In the other definition
>
> void function (struct struct_random *r)
> or
> void function (const struct struct_random *r)
>
> the structure is being passed by the pass by reference method.

No, it isn't. A pointer to the structure is being passed, by value.

<snip>

--
Richard Heathfield :
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
--

Richard Heathfield, Jun 27, 2003
5. ### Micah CowanGuest

"Simon Biber" <> writes:

> "Richard Heathfield" <> wrote:
> > Obviously. All objects are passed by value in C.

>
> Except for objects that cannot be passed as themselves.
> In particular, function parameters never have array type.
>
> When you say all objects are passed by value, I think it
> is important to point out why
> void foo(int arr[5])
> {
> }
> is *not* an exception to that rule.

(So why didn't you?)

The above is not an object that cannot be passed as itself, it just
*looks* like one. C has the slightly confusing property that the
semantics of declarations can differ depending on whether or not it
appears in a function param list.

The above declares the parameter arr to be of type pointer to int, the
same as if it had been prototpyed:

void foo(int *arr)

Since an object of array type decays to pointer in most circumstances,
you are passing that pointer by value.

At any rate, if C did pass arr by reference, then the resulting
parameter would be of type pointer-to-array[5]-of-ints, and not
pointer-to-int.

-Micah

Micah Cowan, Jun 27, 2003
6. ### Richard HeathfieldGuest

Simon Biber wrote:
>
> "Richard Heathfield" <> wrote:
> > Obviously. All objects are passed by value in C.

>
> Except for objects that cannot be passed as themselves.

Sorry; all objects that can be passed ***at all*** are passed by value.

> In particular, function parameters never have array type.

Right.

<snip>

--
Richard Heathfield :
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Richard Heathfield, Jun 27, 2003
7. ### RobGuest

"Rahul Agarkar" <> wrote in message
news:...
> The basic difference between the two methods is the way the struct is
> being passed to the function. When you say

Well, yeah. Passing by pointer is different from passing by value.

>
> void function (struct struct_random r)
>
> the structure is passed through pass by value method. In this, the
> function will create a local copy of the structure and do the desired
> operations.

Sort of. When function(some_struct) is called, the function
receives a copy of some_struct. The mechanism by which

>
> In the other definition
>
> void function (struct struct_random *r)
> or
> void function (const struct struct_random *r)
>
> the structure is being passed by the pass by reference method. In this
> method, a pointer to the structure is passed to the function. In the
> former method, the original copy of the structure will be modified
> inside the function where as the later one protects the original copy
> from being modified.

"pass by reference" simply means that the structure is passed to
the function in a way that avoids creating a copy and which
(potentially) allows modification of the original object. A common
way of implementing that is by passing the address of an object,
but there are other ways of achieving that (eg passing an index
into a compiler managed array).

In C, the value that is passed to a function that takes a pointer
argument is a *copy* of the value of the address. For example.

function(&some_struct)

is equivalent to

struct struct_random *temp = &some_struct;
function(temp);

In other words, it is the *pointer* that is passed by value.

>
> Looking at the above scenarios, it is quite clear that there is no
> definite answer to your question as which method is best. It all

Exactly. It also depends on properties of your compiler and
operating system.

>
> I will give a few scenarios below where each of the above methods are
> given :
> In all these examples, assume there is a structure of an employee.
>
> Scenario 1) The application wants to query the employee information or
> perform some calculations which should not affect the original records
> (for example, calculating the salaries of all the employees. In this
> example, the application just reads the salary of each and every
> employee and adds it up to the total salary). Also assume, there is
> enough memory available on the machine where the application is
> running. In this scenario, one can use following method :
>
> void function (struct struct_random r)
> {
> total += r.salary; file://total is some variable defined globally.
> ...
> }

Apart from philosophical issues such as whether one should or
shouldn't rely on global variables, or whether one should just pass
members of the structure by value to the function (rather than
the whole structure) what you say here is correct.

>
> Scenario 2) The application needs to modify the salary of an
> individual employee. Following method will be suitable :
>
> void function (struct struct_random *r)
> {
> r->salary = 1000;
> ...
> }
>
> Scenario 3) Consider the scenario 1 again. The only changed condition
> is you want to use less memory. This can be done by avoiding the extra
> copies of the struct struct_random in the memory. This method will be
> suitable for the purpose :
>
> void function (const struct struct_random *r)
> {
> ...
> }
>
> Please correct me if i am wrong...
>

In this last scenario, the answer is "it depends". Compilers can optimise
how they pass structures by value in some cases, to reduce memory
overhead. But, as a rough rule of thumb, what you say is correct just
as, again as a rough rule of thumb, you will find that passing a large
struct is less expensive by pointer than by value.

If the performance differences matter, then you need to test to be
sure --- with all compilers you target.

[My original response snipped].
--