Dervin Thunk
Dervin Thunk

Reputation: 20139

When to pass by value?

Dear all. I was wondering if there are examples of situations where you would purposefully pass an argument by value in C. Let me rephrase. When do you purposefully use C's pass-by-value for large objects? Or, when do you care that the object argument is fully copied in a local variable?

EDIT: Now that I think about it, if you can avoid pointers, then do. Nowadays, "deep" copying is possible for mostly everything in small apps, and shallow copying is more prone to pointer bugs. Maybe.

Upvotes: 2

Views: 867

Answers (7)

Michael Dorgan
Michael Dorgan

Reputation: 12515

In C (sans const references), you pass by value for 3 reasons.

  • You don't want the source to be modified by the receiving function outside of its context. This is (was) the standard reason taught in school as it why to pass by value.

  • Passing by value is cheaper if the value fits within the architecture's register - or possibly registers if the compiler is very intelligent. Passing by value means no pointer creation and no dereference to get at the value being passed in. A small gain, but it does add up in certain circumstances.

  • Passing by value takes less typing. A weak reason to be sure, but there it is.

The const keyword negates most of reason 1, but reason 2 still has merit and is the main reason I pass by value.

Upvotes: 3

frankc
frankc

Reputation: 11473

If we're going to be pedantic about this, everyhing in C is pass-by-value. You may pass a pointer by value instead of passing the actual object by value, but it's still pass-by-value.

Anyway, why pass an entire object instead of a pointer to an object? Well, for one, your compiler may be able to optmize the call such that underneath the covers only an address is copied. Also/Alternatively, once you introduce pointers, your compiler may not be able to do as much optimization of your function because of aliasing. It's also less error prone to not have to remember to dereference. The caller can also be sure that what he passed in is not modified (const doesn't really guarantee this, it can be -dangerously- cast away)

Upvotes: 1

rubenvb
rubenvb

Reputation: 76720

I follow as a rule:

  • pass built-in types by value (int, char, double, float...)
  • pass classes and structs by (const) reference. There is no pointer handling involved whatsoever.

Never had any problems with this way of work.

Upvotes: 1

BillThor
BillThor

Reputation: 7586

Depending on how the call stack is built the char and char* may take the same amount of space. It is generally better to have values aligned on word boundaries. The cost of accessing a 32 bit pointer on a word boundary may be significantly lower than accessing it on a non-word boundary.

Passing by value is safer if you don't want the value modified. Passing by reference can be dangerous. Consider passing by referennce

CONST int ONE = 1;
increment( *ONE );
print ONE;

Output is 2 if the constant was modified.

Upvotes: 0

crazyscot
crazyscot

Reputation: 12019

I don't think your argument about chars holds water. Even though your char is conceptually 1 byte, each argument to a function call typically translates to a whole (word-sized) register and to the same amount of space on the stack for efficiency.

You can pass a whole struct on the stack as an argument if you really want to (and, I believe, return them as well). It's a way of avoiding both allocating memory and having to worry about pointer hygiene.

Upvotes: 0

adf88
adf88

Reputation: 4452

Passing by-reference is cheaper because you don't have to create a local copy of an object. If the function needs a local copy (for any purpose) - that could be a case.

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 882078

Well, for one thing, if you want to change it.

Imagine the following contrived function:

int getNextCharAndCount (char *pCh);

Each time you call it, it returns the next most frequent character from a list by returning the count from the function and setting a character by way of the character pointer.

I'm having a hard time finding another use case which would require the pointer if you only ever wanted to use (but not change) the underlying character. That doesn't mean one doesn't exist of course :-)

In addition, I'm not sure what you're discussing is deep/shallow copy. That tends to apply to structures with pointers where a shallow copy just duplicates the top level while a deep copy makes copies of all levels.

What you're referring to is pass-by-value and pass-by-reference.

Upvotes: 1

Related Questions