-3

How to decide whether a function should have a type? I mean, should it have a return type? For example,

double add(double a, double b)
{
double sum;
sum = a + b;
return sum;
}

double sum;
void add(double a, double b, double sum)
{
sum = a + b;
}

are these two same?

Euler
  • 335
  • 2
  • 5
  • 14

3 Answers3

1

A function must always have a type, although the return type can be void. Generally, however, if the function has a value, it should use a return value; functions without return values are usually only used for side effects. (There might be an exception for functions with more than one return value, but such functions should be relatively rare.)

And finally, C++ uses pass by value, so your second example will never modify the global sum. You need to specify pass by non-const reference:

void add( double a, double b, double& sum )...

or use a pointer.

EDIT:

With regards to the performance implications of returning a complex type: C++ has been designed to allow a certain number of optimizations, called RVO (for Return Value Optimization) and NRVO (for Named Return Value Optimization); C++ has added move semantics as well. So performance is rarely a reason to violate good programming practices (which argue for return values). If the profiler does show a problem, however, the best solution is probably something along the lines of:

void
doConcat( std::vector<double> const& a,
          std::vector<double> const& b,
          std::vector<double>& results )
{
    results.reserve( a.size() + b.size() );
    results = a;
    results.insert( results.end(), a.begin(), a.end() );
}

std::vector<double>
Concat( std::vector<double> const& a, std::vector<double> const& b )
{
    std::vector<double> sum;
    doConcat( a, b, sum ):
    return sum;
}

This way, most of the client code can continue using the natural interface, and only the places where the profiler insists will have to use the awkward interface.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • You are right, I tried it before. Yet, I thought even making a pointer and using reference to pass the argument is still not same as declare a return type for the function. I am asking because I am not sure if a return type is a vector of vector, then will this be very slow in a function call?@LuchianGrigore @herohuyongtao – Euler May 06 '14 at 17:40
  • @Euler C++ has been designed to allow the compiler to optimize this sort of thing. And even then... Until the compiler tells you that this is a problem, don't worry about it. – James Kanze May 06 '14 at 17:43
  • @Euler, no, it's not slow. It's literally a non operation (see RVO). Also, don't preoptimize. – Shoe May 06 '14 at 17:44
  • @Jefffrey When you say preoptimize, could you tell me how optimize works in C++? – Euler May 06 '14 at 17:48
  • @Euler, Have you searched "RVO C++" like I recommended you to? – Shoe May 06 '14 at 17:50
0

These are not the same-- in the second function, you are passing in "sum" by value, and so when you do "sum = a + b" you are only doing arithmetic on a local copy.

Correcting this would look like:

void add(double a, double b, double& sum){
sum=a+b;
}

Note the ampersand-- this means you're passing in "sum" by reference, and any changes you do to "sum" in the function will actually change the variable "sum" in the scope of the function that calls it.

In general, if a function logically should have a return type (AKA, it makes senses for the function to have one), then give it one.

druckermanly
  • 2,694
  • 15
  • 27
0

The simple answer is that it depends on what your intention is.

P.S.: For the second:

double sum;
void add(double a, double b, double sum)
{
    sum = a + b;
}

It cannot even change the sum at all, input parameter double sum will hide the global double sum in the function scope and thus global sum will not update after the function.

You probably mean

void add(double a, double b, double &sum)
{
    sum = a + b;
}

To read on, check out Return vs. Not Return of functions?

Community
  • 1
  • 1
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174