i know c++ can pass argument by value and by reference and arrays are passed only by reference to a function. what about vectors? passed by ref or val or both?
1. From the performance point of view you should never pass them by val.
2. From the correctness/safety point of view you should never pass them by ref.
The choice is yours. :D
There is. There are mainly two potential problems that you must think of before passing it by ref:
1. The receiver modifies the vector - might break the caller.
2. The receiver stores the reference to the vector and the caller modifies the vector afterwards - might break the receiver.
The first one can be mitgated by using const ref. But then if the receiver wants to do something with this vector, e.g. store it somewhere, it is forced to make a copy. There is no protection against 2., except making a defensive copy, but this is just as passing it by val. So, in both cases if you want security and lack of strong coupling you are forced to sacrifice performance.
In small programs this is not an issue. In large programs this yields often hard to find bugs - the types of bugs that you sit for a week in front of the debugger and you try to find out why the given variable changed "magically", what did this and why it happens randomly.
Another solution is simply using immutable vector, but there are none in C++, so you must roll your own. However, I haven't seen anyone doing this. Switching to language with a better standard library is easier.
1. if it modifies the vector, that's not a "problem", but rather the purpose or a wanted by-product of the function.
If it doesn't modify the vector, the reference should be const. If it needs a copy, it should make a copy. Simple.
The copy would occur either way when passing by value, whether it's necessary or not.
2. The receiver can't just go and store a reference to an object without knowing anything about its lifetime.
If it does know the passed object will outlive its own lifetime, there is no problem.
In small programs this is not an issue. In large programs this yields often hard to find bugs - the types of bugs that you sit for a week in front of the debugger and you try to find out why the given variable changed "magically", what did this and why it happens randomly.
That's not a problem caused by references, but by poor design, such as no clear object ownership.
That's not a problem caused by references, but by poor design, such as no clear object ownership
You see, "in nature" there is no such thing like object ownership. Objects just are. Object ownership is an imperfect solution created to overcome problems with references to mutable data.
And this is why I have written that in small programs this is not a problem. In small programs it is easy to keep ownership and object lifetime clean. But in large programs, written by many people at different times, keeping clear ownership is difficult. Besides, for some kinds of objects having an owner is a limitation, causing additional complexity. E.g. when you optimize things, you cannot just take a frequently called function and cache its results, without analyzing the whole program (not the function implementation itself). You could cause a disaster by such an optimization.
In C++ it is not possible to pass a complete block of memory by value as a parameter to a function, but we are allowed to pass its address. In practice this has almost the same effect and it is a much faster and more efficient operation.
now i wanna know is it possible to pass vector by value???(i think it's not cuz it's a block of memory)
if we have
vector<int> b
function(b)
then we pass b by ref/is that right?
(i am trying to write huffman coding using vectors and i do want to modify it in reciever function.)
Both. But:
1. From the performance point of view you should never pass them by val.
2. From the correctness/safety point of view you should never pass them by ref.
The choice is yours. :D
The vector has an overloaded copy-constructor and it would copy the data by itself when passed by val. But if you want to modify the passed arguments, you should pass by val. Functions modifying their arguments are poor design.
@sourena: your function signature should look like this:
void function(std::vector<int>& vec);
Passing by reference should mean you're going to modify the object. Passing by const reference should mean you just need to read the object. Passing by value should mean you need to copy the object. Just keep these "rules" in mind.
void func(std::vec<int>& list); // to process/populate the list
you should use:
std::vector<int> func(); // creates a new list
Both have the same performance but the intent is much more clear in the second one. Objects should be created in their final state immediately as often as possible. The return value is for returnig data from functions, the arguments are for passing data to functions.
Making a copy and then returning a copy doesn't make a lot of sense for a processing function
This is true only in such languages like C++, where making a copy of the list is very costly i.e. O(n). In many languages making a copy of the list is an O(1) operation and then this pattern makes perfectly sense.
This is true only in such languages like C++, where making a copy of the list is very costly i.e. O(n). In many languages making a copy of the list is an O(1) operation and then this pattern makes perfectly sense.
Out of curiosity, which languages can copy n items in O(1) time?
That's like saying "Functions returning values is poor design because I can't automatically know what the value will be."
Tell it your maths teacher. :D
Functions assign a return value to their arguments. So:
1. arguments = input
2. return value = output
Just because you can use arguments for output in C/C++ functions (so they are procedures returning a value, but not functions in mathematical sense) does not mean you should use it whenever posssible. Ok, actually sometimes there is no other solution, but you should not do it as a default. I find it bad style.
Out of curiosity, which languages can copy n items in O(1) time?
All that use immutable lists/vectors/maps in their standard libraries. Scala, Haskell, OCaml, ML, LISP. You just don't need to ever make copy - you pass reference where in C/C++ you would have to make a copy.
does not mean you should use it whenever posssible.
Agreed. When did we state you should always use it?
All that use immutable lists/vectors/maps in their standard libraries. Scala, Haskell, OCaml, ML, LISP. You just don't need to ever make copy - you pass reference where in C/C++ you would have to make a copy.
Then you aren't copying n items, you are basically making a pointer/reference to it. A C++ list is a mutable list. If you want an immutable list, you just pass it by const reference.
Then you aren't copying n items, you are basically making a pointer/reference to it
Semantically they are the same if only the data structure is immutable. The compiler is free to choose, whether it makes a copy or pass a reference (making a copy can sometimes be much more efficient, in case of NUMA architectures). There is no need to have that distinction in the language.
If you want an immutable list, you just pass it by const reference
Immutable != const. Const does not protect from the problem of modifying the list by the caller afterwards. So does not guarantee immutability, even the shallow one. It is much weaker. Thus in C++ pass by ref has different semantics than pass by val, regardless it is const or not. If I'm gonna do something with the received vector afterwards, I need to either make a copy (inefficient) or prey that someone doesn't screw my code by modifying the caller code (which may be totally different module, written by a different person).
Pass by ref makes my code easily breakable by changes in other places of code, not directly coupled with my code. So, pass by ref (or pass by pointer) introduces hidded code dependencies that are difficult to maintain in a code base of 1 million SLOC. It breaks encapsulation and simply doesn't scale up. This is why most modern languages use immutable strings as a basic data structure for text and not mutable ones like in STL.
BTW: Passing by const ref forces me to do costly O(n) copy whenever I need to change something in the vector/list. If this was an immutable vector I still would be able to work on it efficiently - adding or removing items can be still O(1) or O(log n) on persistent structures (there are no in STL or Boost).