Question about passing by value

M

Method Man

I understand that arrays and structs can't be passed by value into and out
of functions since they can be arbitrarily big. My question is: Why are
types allowed to be passed by value? Couldn't my types be arbitraily big as
well?
 
V

Victor Bazarov

Method said:
I understand that arrays and structs can't be passed by value into and out
of functions since they can be arbitrarily big.

You understand incorrectly, but only partially so. Objects of class
type _can_ be passed into functions and returned from functions by
value. Arrays cannot because they are not objects.
My question is: Why are
types allowed to be passed by value? Couldn't my types be arbitraily big as
well?

I am not sure what you mean here.

Victor
 
C

chris

Method said:
I understand that arrays and structs can't be passed by value into and out
of functions since they can be arbitrarily big. My question is: Why are
types allowed to be passed by value? Couldn't my types be arbitraily big as
well?

The simple answer is that long, long ago it was decided by the people
who designed C that arrays would be passed by reference instead of
value. If this was the best choice is open to debate, however we are
stuck with it now :)

In C++ it was decided that all classes should by default be passed by
value, as they were designed with the intention of being like the built
in types like int, char, etc rather than like arrays (note that this is
different to Java, where they are passed by reference). This was also a
decision which was made, and now we have to live with that too :)

Chris
 
A

Andrey Tarasevich

Method said:
I understand that arrays and structs can't be passed by value into and out
of functions since they can be arbitrarily big.

That's not entirely true. Structs _can_ be passed by value into and out
of function, regardless of how big they are. Arrays cannot, but not
because of their potential size, but rather because arrays are neither
assignable nor copy-constructible. This limitation for arrays has mostly
historical reasons.
My question is: Why are
types allowed to be passed by value? Couldn't my types be arbitraily big as
well?

What "your types"? Your non-scalar types in most cases will also be
"arrays or structs (classes)". How is that different from the first part
of the question?
 
J

JKop

Method Man posted:
I understand that arrays and structs can't be passed by value into and
out of functions since they can be arbitrarily big.

Incorrect.

They can.

It's just that it's recommended against in certain
circumstances.
My question is: Why
are types allowed to be passed by value? Couldn't my types be
arbitraily big as well?

Yes, but you've the choice.

Choice is better than no choice.

There's times when I *do* pass a string by value, or return
one by value.


-JKop
 
M

Method Man

Victor Bazarov said:
You understand incorrectly, but only partially so. Objects of class
type _can_ be passed into functions and returned from functions by
value. Arrays cannot because they are not objects.

Hmm, I'm not sure why I included structs. My mistake.
I am not sure what you mean here.

Sorry, I wasn't clear on my intent. Here's an example:

If I create a type with an array as a data member, and I'm allowed to pass
an object of my type by value into a function, wouldn't all its members be
copied over (incl. the array)? So how would this work?
 
D

Default User

Method said:
I understand that arrays and structs can't be passed by value into
and out of functions since they can be arbitrarily big.


As others have pointed out, your assertion about structs is incorrect.
It's not correct for C either. In fact, one way of handling the array
problem is to wrap the array in a struct. That's mostly useful for C,
in C++ the vector standard container is available.



Brian Rodenborn
 
M

Mike Wahler

Method Man said:
Hmm, I'm not sure why I included structs. My mistake.
big

Sorry, I wasn't clear on my intent. Here's an example:

If I create a type with an array as a data member, and I'm allowed to pass
an object of my type by value into a function, wouldn't all its members be
copied over (incl. the array)?
Yes.

So how would this work?

struct myType
{
char text[100];
int other;
};

void foo(myType param)
{
}

int main()
{
struct myType obj = {"hello", 0};
foo(obj);
return 0;
}

-Mike
 
A

Andrey Tarasevich

Method said:
...
If I create a type with an array as a data member, and I'm allowed to pass
an object of my type by value into a function, wouldn't all its members be
copied over (incl. the array)?
Yes.

So how would this work?

Hmm... They are just copied. One subobject after another. Which also
applies to arrays. Arrays are copied element by element.
 
J

JKop

Andrey Tarasevich posted:
Hmm... They are just copied. One subobject after another. Which also
applies to arrays. Arrays are copied element by element.

Even if you have complicated ones:

struct blah
{
std::string a[6];
std::vector b[8];
};

When you pass it by value, their copy constructors will be
called, ie. 6 copy constructed strings, 8 copy constructed
vectors!

-JKop
 
G

Greg Comeau

I understand that arrays and structs can't be passed by value into and out
of functions since they can be arbitrarily big. My question is: Why are
types allowed to be passed by value? Couldn't my types be arbitraily big as
well?

"Original C" did not allow structs to be passed or returned
(or assigned), but now does, as does C++ (with different rules
for non-PODs). As I understood it, the premise of the original
C constraint is that passing such items can be expensive.
Ditto for arrays (which have some of their own issues too).

Even with their allowance they can be. But yes, even your
types can be. For instance, a struct with 1000 int members
is surely larger than a array of 5 chars. So as usual,
as the programmer, you need to be aware of what you're doing
in any situation.

If this is not what you mean, please elaborate in the NG.
 
M

Method Man

JKop said:
Andrey Tarasevich posted:
Hmm... They are just copied. One subobject after another. Which also
applies to arrays. Arrays are copied element by element.

Even if you have complicated ones:

struct blah
{
std::string a[6];
std::vector b[8];
};

When you pass it by value, their copy constructors will be
called, ie. 6 copy constructed strings, 8 copy constructed
vectors!

Ok, I think I understand now. I'll attempt to summarize what I got from this
thread.

An array itself can't be passed by value because it is not an object and not
copy-constructable. But if we simply wrap our array in a struct or class and
pass an object of that type by value, the compiler copies the array for us
element-by-element.

Sounds to me like the original restriction on arrays is pointless. I guess
I'll live ;)
 
M

Method Man

Greg Comeau said:
"Original C" did not allow structs to be passed or returned
(or assigned), but now does, as does C++ (with different rules
for non-PODs). As I understood it, the premise of the original
C constraint is that passing such items can be expensive.
Ditto for arrays (which have some of their own issues too).

Thanks for clearing that up.
 
J

Jack Klein

JKop said:
Andrey Tarasevich posted:
Method Man wrote:
...
If I create a type with an array as a data member, and I'm allowed to
pass an object of my type by value into a function, wouldn't all its
members be copied over (incl. the array)?

Yes.

So how would this work?

Hmm... They are just copied. One subobject after another. Which also
applies to arrays. Arrays are copied element by element.

Even if you have complicated ones:

struct blah
{
std::string a[6];
std::vector b[8];
};

When you pass it by value, their copy constructors will be
called, ie. 6 copy constructed strings, 8 copy constructed
vectors!

Ok, I think I understand now. I'll attempt to summarize what I got from this
thread.

An array itself can't be passed by value because it is not an object and not
copy-constructable. But if we simply wrap our array in a struct or class and
pass an object of that type by value, the compiler copies the array for us
element-by-element.

No, an array is an object. The definition of the term 'object' in C++
has nothing at all to do with 'object oriented programming' or with
classes or user defined types.

Bare arrays are not copyable in C and C++ because of limitations that
existed when C was developed 30 odd years ago, given the type of
programming and programmers it was originally intended for.

If either C or C++ was ever changed to make bare arrays copyable, or
passable to and returnable from functions, some new syntax would have
to be developed, it couldn't be just by using the unadorned name of
the array.

If the automatic conversion from array name to pointer to first
element in function calls and return statements was ever changed, it
would break 99% of all the C and C++ programs that have ever existed.
Sounds to me like the original restriction on arrays is pointless. I guess
I'll live ;)

It wouldn't have been so pointless if, 30 plus years ago, you were an
expert systems programmer on the typical small minicomputers of the
day and your objective was to make a reasonably portable high level
language compact and efficient enough so that it could be used to
write operating systems, instead of assembly language in which they
were all written in up to that time.

I doubt if anyone was more surprised than Dennis Ritchie to see the
range of platforms and applications that C has taken on. Not to
mention the even larger applications done in C++.
 
R

Richard Herring

Method Man <[email protected]> said:
Sounds to me like the original restriction on arrays is pointless. I guess
I'll live ;)

It's inherited from C. Because in most contexts the name of an array
"decays" to a pointer to its first element, there's usually no way to
tell the compiler that what you want to pass is the whole array, not
just the pointer.
 
G

Greg Comeau

JKop said:
Andrey Tarasevich posted:
Method Man wrote:
...
If I create a type with an array as a data member, and I'm allowed to
pass an object of my type by value into a function, wouldn't all its
members be copied over (incl. the array)?

Yes.

So how would this work?

Hmm... They are just copied. One subobject after another. Which also
applies to arrays. Arrays are copied element by element.

Even if you have complicated ones:

struct blah
{
std::string a[6];
std::vector b[8];
};

When you pass it by value, their copy constructors will be
called, ie. 6 copy constructed strings, 8 copy constructed
vectors!

Ok, I think I understand now. I'll attempt to summarize what I got from this
thread.

An array itself can't be passed by value because it is not an object and not
copy-constructable.

The array is an object, just ends up being a second class citizen
for various reasons.
But if we simply wrap our array in a struct or class and
pass an object of that type by value, the compiler copies the array for us
element-by-element.

Well, it copies it.
Sounds to me like the original restriction on arrays is pointless. I guess
I'll live ;)

No, very pointful. Rememeber that C started out as a systems
programming language. So it was used for things like building
operating systems. You really did not want arrays passed
by value so willy-nilly. Slapping them down into pointers
to their first elements that get passed instead made sense.
As with all things, it's a compromise, so that's not always
going to be what you want. Languages and machines have
evolved over the years, but adding array copying now would
require different syntax, and with things like C++'s
std::string, std::venctor<> etc, this is "exactly" what we've got
to some extent. Those additions to have their own issues
and compromises.
 
A

Andrey Tarasevich

Jack said:
...
If either C or C++ was ever changed to make bare arrays copyable, or
passable to and returnable from functions, some new syntax would have
to be developed, it couldn't be just by using the unadorned name of
the array.

And why exactly is the reason for that, in your opinion? Backward
compatibility considerations that you mention later? Aside from that, I
don't see any other reason for any syntax changes.
If the automatic conversion from array name to pointer to first
element in function calls and return statements was ever changed, it
would break 99% of all the C and C++ programs that have ever existed.

That's definitely true.
 
G

Greg Comeau

And why exactly is the reason for that, in your opinion? Backward
compatibility considerations that you mention later? Aside from that, I
don't see any other reason for any syntax changes.

What for instance would this do:

"xyz" = "a";

?

What would say sizeof this new array allowance do? And when?

And so on.
 
A

Andrey Tarasevich

Greg said:
What for instance would this do:

"xyz" = "a";

?

Generate a diagnostic because of type incompatibility: 'char[4]' against
'char[2]'. Even if array sizes were the same it would still generate a
diagnostic for an attempt to modify a non-modifiable lvalue.
What would say sizeof this new array allowance do? And when?

I don't understand this question. Could you please rephrase that?
 
I

Ivan Vecerina

Jack Klein said:
No, an array is an object. The definition of the term 'object' in C++
has nothing at all to do with 'object oriented programming' or with
classes or user defined types. ....
If either C or C++ was ever changed to make bare arrays copyable, or
passable to and returnable from functions, some new syntax would have
to be developed, it couldn't be just by using the unadorned name of
the array.

I think that tr1 already brings us a solution:
template<class T, size_t N> struct array;
(6.2 in http://open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1687.pdf)

When you want your array to be copied by value, replace:
float foo[10];
with:
array<float,10> foo;

As a bonus, you'll get a container-compatible interface
including begin(), end(), etc.


Cheers -Ivan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top