Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

advantage of returning values through the argument list

0 views
Skip to first unread message

Siemel Naran

unread,
Oct 7, 2004, 6:00:17 AM10/7/04
to
Hi. I have found one advantage of returning values through the argument
list. It's that we have to store the return value. But when we return by
value, we may forgot to store the return value.


Consider,

void f(int x, int& i);
int i, j;
f(1, i);
f(2, j);


But

int f(int x);
int i, j;
i = f(1);
j = f(2);


Generally, return by value functions leads to code that is easier to read.
This appears to be the case in the short example above. But with return by
value functions, we may forget to store the return value in 'i' or 'j'.
With returning functions through the function argument list, this is
impossible.

This becomes more important when writing more complicated code, where we
might assign to the same variable twice.

result = f(3);
if (!result) {
result = f(4);
}

Seems somewhere we might just write "f(4);" rather than "result = f(4);".

Any comments?


JKop

unread,
Oct 7, 2004, 7:52:25 AM10/7/04
to
Siemel Naran posted:


With respect, I think your argument is bullshit. Next thing we'll have
compilers saying:

Warning: line 5: x += 365
: Are you sure? Because this year is a leap year
: Perhaps you meant 366?


There only advantage I recognize with your method, I shall illustrate it in
the following:

Firstly, here's the class I'll work with. You don't have to pay too much
attention to this part, skip on to the actual "main" code:


#include <iostream>
#include <cstdlib>

class AnyClass
{
public:

unsigned play_member;

private:

static unsigned object_counter_PRIVATE;
char* name_PRIVATE;

public:

static unsigned const &object_counter;
const char* const &name;

private:

bool const has_dynamically_allocated_name;

public:

AnyClass(const char* const in_name) : has_dynamically_allocated_name
(false), name(name_PRIVATE)
{
const_cast<const char* &>(name_PRIVATE) = in_name;

++object_counter_PRIVATE;
std::cout << " AnyClass Constructor for: " << name_PRIVATE <<
'\n';
}

AnyClass(AnyClass const &original) : has_dynamically_allocated_name
(true), name(name_PRIVATE)
{
std::size_t length = std::strlen( original.name_PRIVATE );

name_PRIVATE = new char[length + 1 + 10]; //1 for the null
character

memcpy( name_PRIVATE, "Copy of \"" , 9 );

memcpy( &name_PRIVATE[9], original.name_PRIVATE, length );

name_PRIVATE[ 9 + length ] = '\"';
name_PRIVATE[ 9 + length + 1 ] = '\0';

++object_counter_PRIVATE;
std::cout << "AnyClass Copy Constructor for: " << name_PRIVATE <<
'\n';
}

~AnyClass()
{
std::cout << " AnyClass Destructor for: " << name_PRIVATE <<
'\n';

if (has_dynamically_allocated_name) delete [] name_PRIVATE;
--object_counter_PRIVATE;
}
};

unsigned AnyClass::object_counter_PRIVATE = 0;
unsigned const &AnyClass::object_counter = AnyClass::object_counter_PRIVATE;

And now here's the code:

AnyClass Function1()
{
AnyClass poo = AnyClass("poo"); //Just for kicks!

poo.play_member = 6;

poo.play_member += 32;

return poo;
}

void Function2(AnyClass &in)
{
in.play_member = 6;

in.play_member += 32;
}

int main()
{
Function1();

AnyClass monkey("monkey");
Function2(monkey);
}

When I compile it with "g++ -ansi -pedantic", it prints the following:

AnyClass Constructor for: poo
AnyClass Destructor for: poo
AnyClass Constructor for: monkey
AnyClass Destructor for: monkey


But... when I compile it with "g++ -ansi -pedantic -fno-elide-constructors",
it prints the following:


AnyClass Constructor for: poo
AnyClass Copy Constructor for: Copy of "poo"
AnyClass Destructor for: poo
AnyClass Copy Constructor for: Copy of "Copy of "poo""
AnyClass Destructor for: Copy of "poo"
AnyClass Destructor for: Copy of "Copy of "poo""
AnyClass Constructor for: monkey
AnyClass Destructor for: monkey


...simulating a shit compiler.


So there's *one* advantage with your method.

Then there's the *dis*advantage - you can't work with the constructor.

-JKop

Karl Heinz Buchegger

unread,
Oct 7, 2004, 9:36:25 AM10/7/04
to
Siemel Naran wrote:
>
[snip]

> result = f(3);
> if (!result) {
> result = f(4);
> }
>
> Seems somewhere we might just write "f(4);" rather than "result = f(4);".

Seems like you are saying that for the same argumentation the language
should force us to write

add( i, 2 + 5 );

instead of

i = 2 + 5;

because someone might 'forget' to use the result of the addition.


Seriously: In 20 years I have never 'forgotten' to use the return
value of a function if I needed that return value for something.
And believe me, I have 'forgotten' a lot of things to do. But never
to assign the return value if I needed it for other calulations or
I/O or storing in data base.


--
Karl Heinz Buchegger
kbuc...@gascad.at

JKop

unread,
Oct 7, 2004, 9:46:44 AM10/7/04
to

> int main()
> {
> Function1();
>
> AnyClass monkey("monkey");
> Function2(monkey);
> }


I'm such a fool! Should've been

int main()
{
AnyClass cheese = Function1();

AnyClass monkey("monkey");
Function2(monkey);
}


recompiling I get:

g++ -ansi -pedantic


AnyClass Constructor for: poo


AnyClass Constructor for: monkey
AnyClass Destructor for: monkey

AnyClass Destructor for: poo

g++ -ansi -pedantic -fno-elide-constructors

AnyClass Constructor for: poo
AnyClass Copy Constructor for: Copy of "poo"
AnyClass Destructor for: poo
AnyClass Copy Constructor for: Copy of "Copy of "poo""
AnyClass Destructor for: Copy of "poo"

AnyClass Copy Constructor for: Copy of "Copy of "Copy of "poo"""


AnyClass Destructor for: Copy of "Copy of "poo""
AnyClass Constructor for: monkey
AnyClass Destructor for: monkey

AnyClass Destructor for: Copy of "Copy of "Copy of "poo"""


-JKop

JKop

unread,
Oct 7, 2004, 9:53:08 AM10/7/04
to

> g++ -ansi -pedantic
>
>
> AnyClass Constructor for: poo
> AnyClass Constructor for: monkey
> AnyClass Destructor for: monkey
> AnyClass Destructor for: poo


2 objects created. No temporaries. Yipee!


> g++ -ansi -pedantic -fno-elide-constructors
>
> AnyClass Constructor for: poo
> AnyClass Copy Constructor for: Copy of "poo"
> AnyClass Destructor for: poo
> AnyClass Copy Constructor for: Copy of "Copy of "poo""
> AnyClass Destructor for: Copy of "poo"
> AnyClass Copy Constructor for: Copy of "Copy of "Copy of "poo"""
> AnyClass Destructor for: Copy of "Copy of "poo""
> AnyClass Constructor for: monkey
> AnyClass Destructor for: monkey
> AnyClass Destructor for: Copy of "Copy of "Copy of "poo"""


5 objects created, 3 of which are temporaries.


-JKop

Howard

unread,
Oct 7, 2004, 11:23:27 AM10/7/04
to

"Siemel Naran" <Sieme...@REMOVE.att.net> wrote in message
news:Rs89d.673168$Gx4.4...@bgtnsc04-news.ops.worldnet.att.net...

I see no need for such a requirement. In fact, it may be perfectly valid do
discard the return value of a function. It might be that the return value
is simply an indicator of some sort, such as how many items are now in the
container after calling an Add function on it. Of the writer of the
function might provide a return value COPY of a modified parameter, ALLOWING
the caller to assign it to another variable, but not REQUIRING it.

Usually, I return by parameter when I have more than one passed object to be
modified, or if I need the return value to indicate success/failure or some
other salient info.

Your design should dictate what you need to return and how, not some rote
practice that you think solves a general problem.

-Howard

(BTW, let me apologize for JKop's rudeness in his reply. He does not
represent the general opinions of this group. He's young and brash, and
when he disagrees, he tends to emit rude noises. :-))

Howard

unread,
Oct 7, 2004, 11:25:48 AM10/7/04
to

"Howard" <ali...@hotmail.com> wrote in message
news:Pbd9d.504039$OB3.75481@bgtnsc05-

> I see no need for such a requirement. In fact, it may be perfectly valid
do

should be "perfectly valid TO", not "perfectly valid do"

> discard the return value of a function. It might be that the return value
> is simply an indicator of some sort, such as how many items are now in the
> container after calling an Add function on it. Of the writer of the

should be "OR the writer", not "Of the writer".


Haven't had my coffee yet... :-)

-Howard


0 new messages