C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

structs passed by value

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language
View previous topic :: View next topic  
Author Message
Mantorok Redgormor
Guest





PostPosted: Sun Dec 28, 2003 5:06 am    Post subject: structs passed by value Reply with quote



When you pass a struct by value how is it
suppose to be handled internally?

Passing say an int by value is simple
since the contents of which can be held by a register
or some other means, allocating space on the stack etc

But for a struct? Since structs can describe more than
one type, it is confusing to think how it is handled
internally when passing by value to other functions.



--
nethlek
Back to top
Jack Klein
Guest





PostPosted: Sun Dec 28, 2003 5:54 am    Post subject: Re: structs passed by value Reply with quote



On 27 Dec 2003 21:06:16 -0800, [email]nethlek (AT) tokyo (DOT) com[/email] (Mantorok Redgormor)
wrote in comp.lang.c:

Quote:
When you pass a struct by value how is it
suppose to be handled internally?

However the compiler wants to.

Quote:
Passing say an int by value is simple
since the contents of which can be held by a register
or some other means, allocating space on the stack etc

The language standard does not specify how anything is passed to a
function, merely that the called function gets a copy. Furthermore,
each call to the function gets its own unique copy. If a function
that receives a structure by value calls itself recursively, the
second invocation must receive a fresh copy.

Quote:
But for a struct? Since structs can describe more than
one type, it is confusing to think how it is handled
internally when passing by value to other functions.

It makes no difference at all what the number and types of the members
of the structure are, conceptually. An implementation must provide
memory somewhere (perhaps on the "stack", if the implementation uses
one, perhaps allocated with malloc()), and then it can copy the
original structure into the new block of memory with memcpy() or
something that works similarly.

It is highly unlikely that the compiler would actually generate the
copy of the structure by assigning member-by-member (although it
could, as nothing in the language standard prevents it). In most
cases, memcpy() or some intrinsic equivalent byte copying routine is
used. So the low level code that makes the copy does not need to know
anything at all about the members or their types, merely the size of
the structure.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Back to top
Chris Torek
Guest





PostPosted: Sun Dec 28, 2003 8:21 am    Post subject: Re: structs passed by value Reply with quote



Quote:
On 27 Dec 2003 21:06:16 -0800, [email]nethlek (AT) tokyo (DOT) com[/email] (Mantorok Redgormor)
wrote in comp.lang.c:
When you pass a struct by value how is it
suppose to be handled internally?

In article <news:2jrsuv82ra58c0jj0j886lut5mgqml1tou (AT) 4ax (DOT) com>
Jack Klein <jackklein (AT) spamcop (DOT) net> answers:
Quote:
However the compiler wants to.

Indeed.

There are only two commonly-used mechanisms, though: either the
caller makes a copy, or the callee makes a copy.

One of the two must do so unless the compiler can guarantee that
"not making a copy" is indistinguishable to the program from "making
a copy". That includes things like ¶m != &orig, e.g.:

#include <stdio.h>

struct S { int a[1000]; };

void f(void);
void g(struct S);

static struct S *some_s;

void f(void) {
struct S localvar;

some_s = &localvar;
g(localvar);
}

void g(struct S arg) {
if (some_s == &arg)
puts("aha, compiler failed to copy it!");
else
puts("compiler apparently made a copy");
}

int main(void) { f(); return 0; }

If neither f() nor g() copies localvar, g() will detect the
compiler's failure -- unless the compiler is REALLY clever and
changes the if to "if (0)" even though some_s == &arg. :-)

Normally this sort of optimization -- avoiding the copy, then
rewriting comparisons to pretend the pointers are not equal even
though they are -- is not even attempted. Experienced C programmers
know that the copy happens and is expensive, so they avoid paying
the price by passing &localvar instead. This relieves some of the
pressure on compiler-writers, who can say: "Ah, well, no experienced
programmer would code it that way without good reason, so there is
no reason for me to bother trying to optimize it." This then feeds
back into programmers' experience: copies are expensive, so that
experienced programmers do not make them, so that compilers do not
optimize them, so that programmers do not make them, so....

(Implementations that have stacks often, but not always, have
"caller makes the copy" rules, even though "callee makes the copy"
tends to be more efficient. In particular, compilers that use a
callee-copies rule can remove the copy using nothing but simple
local information: if the copy's address is never taken and the
copy is never modified, the copy need not be made. In other words,
if g() secretly gets a "struct S *argp", all "arg.foo"s can become
"argp->foo"s if there is no &arg and no arg.foo=val. Otherwise,
g() can have a local "arg" variable and do "arg = *argp" and all
will be fine.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

Back to top
EventHelix.com
Guest





PostPosted: Mon Dec 29, 2003 1:42 am    Post subject: Re: structs passed by value Reply with quote

The compiler does a memory copy of the passed structure to the stack
before the function is called. In C the calling function is responsible
for pushing all the parameters on the stack.

The following article discusses the stack copying mechanism:

http://www.eventhelix.com/RealtimeMantra/Basics/CToAssemblyTranslation.htm

Sandeep
--
http://www.EventHelix.com/EventStudio
EventStudio 2.0 - Generate Sequence Diagrams and Use Case Diagrams in PDF
Back to top
CBFalconer
Guest





PostPosted: Mon Dec 29, 2003 3:52 am    Post subject: Re: structs passed by value Reply with quote

"EventHelix.com" wrote:
Quote:

The compiler does a memory copy of the passed structure to the
stack before the function is called. In C the calling function
is responsible for pushing all the parameters on the stack.

The following article discusses the stack copying mechanism:

C does not have a stack. Some C implementations do. The actual
mechanism used is OT on c.l.c, although examples of differenct
systems may be of interest to some.

Compilers do not do copying. They may generate code to do so.

Please learn to differentiate example mechanisms from the actions
required. The latter are detailed in the C standard.

Jack Klein and Chris Torek gave accurate answers at least 5 hours
before you gave your flawed one. I guess we can attribute your
missing those to your use of google groups, with the attendant
delays.

--
Chuck F (cbfalconer (AT) yahoo (DOT) com) (cbfalconer (AT) worldnet (DOT) att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!



Back to top
EventHelix.com
Guest





PostPosted: Mon Dec 29, 2003 11:01 am    Post subject: Re: structs passed by value Reply with quote

CBFalconer <cbfalconer (AT) yahoo (DOT) com> wrote

Quote:
"EventHelix.com" wrote:

The compiler does a memory copy of the passed structure to the
stack before the function is called. In C the calling function
is responsible for pushing all the parameters on the stack.


OOPS! should have said compiler generated code does a memory copy...

Sandeep

Back to top
Jack Klein
Guest





PostPosted: Wed Dec 31, 2003 4:41 pm    Post subject: Re: structs passed by value Reply with quote

On 29 Dec 2003 03:01:24 -0800, [email]eventhelix (AT) hotmail (DOT) com[/email] (EventHelix.com)
wrote in comp.lang.c:

Quote:
CBFalconer <cbfalconer (AT) yahoo (DOT) com> wrote

"EventHelix.com" wrote:

The compiler does a memory copy of the passed structure to the
stack before the function is called. In C the calling function
is responsible for pushing all the parameters on the stack.


OOPS! should have said compiler generated code does a memory copy...

Sandeep

Still not necessarily correct. On many popular RISC architectures
today, a small structure might be passed entirely in registers. ARM
or PowerPC, for example, in fact most modern architectures other than
the register starved x86.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Back to top
Dave Thompson
Guest





PostPosted: Mon Jan 05, 2004 7:02 am    Post subject: Re: structs passed by value Reply with quote

On 28 Dec 2003 08:21:35 GMT, Chris Torek <nospam (AT) torek (DOT) net> wrote:

Quote:
On 27 Dec 2003 21:06:16 -0800, [email]nethlek (AT) tokyo (DOT) com[/email] (Mantorok Redgormor)
wrote in comp.lang.c:
When you pass a struct by value how is it
suppose to be handled internally?

In article <news:2jrsuv82ra58c0jj0j886lut5mgqml1tou (AT) 4ax (DOT) com
Jack Klein However the compiler wants to.

Indeed.

There are only two commonly-used mechanisms, though: either the
caller makes a copy, or the callee makes a copy.

One of the two must do so unless the compiler can guarantee that
"not making a copy" is indistinguishable to the program from "making
a copy". <snip example> In particular, compilers that use a
callee-copies rule can remove the copy using nothing but simple
local information: if the copy's address is never taken and the
copy is never modified, the copy need not be made. <snip

Surely (don't call me be, or at least is not, modified through another path". Sometimes
(often?) implemented as the rather stricter "and there is no store to
any lvalue of the same (struct) type (unless local hence known
distinct) nor to one of character type (that might alias the struct),
nor intervening call to another function that might do so."

- David.Thompson1 at worldnet.att.net

Back to top
Chris Torek
Guest





PostPosted: Mon Jan 05, 2004 11:28 pm    Post subject: Re: structs passed by value Reply with quote

Quote:
On 28 Dec 2003 08:21:35 GMT Chris Torek <nospam (AT) torek (DOT) net> wrote:
One of the two must do so unless the compiler can guarantee that
"not making a copy" is indistinguishable to the program from "making
a copy". <snip example> In particular, compilers that use a
callee-copies rule can remove the copy using nothing but simple
local information: if the copy's address is never taken and the
copy is never modified, the copy need not be made. <snip

In article Dave Thompson <david.thompson1 (AT) worldnet (DOT) att.net> wrote:
Quote:
Surely (don't call me <G>) "and the secretly-uncopied struct cannot
be, or at least is not, modified through another path". Sometimes
(often?) implemented as the rather stricter "and there is no store to
any lvalue of the same (struct) type (unless local hence known
distinct) nor to one of character type (that might alias the struct),
nor intervening call to another function that might do so."

Er, yes. This is the same "alias analysis" problem an optimizer
faces in dealing with arrays, for instance. You cannot quite use
"same struct type", because something like this:

void f1(struct byvalue val) {
extern int *p;

printf("before: val.someint = %dn", val.someint);
*p = 42;
printf("after: val.someint = %dn", val.someint);
}

must not show val.someint changing to 42. Unlike the (pseudo)
array parameter problem, however, an optimizer *can* simply cache
val.someint -- if this were instead:

void f2(int arr[]) {
... same code as before ...
}

and we were printing arr[3], the optimizer *would* have to
reload arr[3] in case the reference via *p changed it to 42.

In other words, it is OK if some or all of the "secretly-uncopied"
(as you put it) struct parameter is eventually modified, *provided*
the compiler caches (copies) the potentially-modified values first.
A write through an otherwise unconstrained lvalue -- such as *p
above -- whose type matches any element type, including (recursively)
any sub-structures or unions within the structure, or through one
of character type, forces at least some copying. Calls to
un-expandable functions that might do this likewise forces a copy.

(It is not all that uncommon to have a leaf function -- one that
makes no additional function calls -- that also uses nothing but
local variables that cannot alias the original structure that the
compiler is "secretly-not-copying". But it is not all that
common either, and -- as I noted earlier -- there is a sort of
chicken-and-egg problem that leads programmers not to pass large
structures by value because it is inefficient because compilers
do not optimize it because programmers do not do it.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

Back to top
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language All times are GMT
Page 1 of 1

 
 


Powered by phpBB © 2001, 2006 phpBB Group