Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 2 questions about struct copy

Reply
Thread Tools

2 questions about struct copy

 
 
Flash Gordon
Guest
Posts: n/a
 
      03-05-2006
P Boy wrote:
> Here http://www.le.ac.uk/cc/tutorials/c/ccccstrc.html is a good source
> about struct copying.


I would not recommend that start. It recommends doing things which are
generally considered bad style around here, such as casting the return
value of malloc (I can only remember one person on this group with a
good reason to do this, and his reason does not apply to most people)
and using sizeof(type) rather than sizeof *ptr to work out how much
space to allocate. I.e. the web page recommends using, and I quote:
ptr = (*int) malloc(sizeof(int)*N)
The generally recommended style around here is the far simpler and more
maintainable form:
ptr = malloc(N * sizeof *ptr);
Fewer characters to type, remains correct of the type of ptr changes,
and does not hide the required diagnostic if there is no declaration of
malloc in scope.

It also goes on to recommend using #define to create an alias for a
type, which is what the typedef keyword is for, and typedef has
advantages over a #define.

Also, please quote some context when replying so that people know what
you are replying to. It is entirely possible that some people might see
your reply but not the original message. See
http://cfaj.freeshell.org/google/ for more about this problem and how to
post correctly through Google. Also see my sig for a link to a lot
more information on what is considered acceptable in the group and why.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
 
 
 
David R Tribble
Guest
Posts: n/a
 
      03-06-2006
Micah Cowan <(E-Mail Removed)> writes:
>> Except that the above text says that the value of a /member/ of the
>> structure or union object may be a trap representation. It will have
>> been read in the assignment, I should think.

>


Keith Thompson wrote:
> Not necessarily. Structure assignment *may* be done as if by calling
> memcpy(), i.e., copying the raw bytes; this would avoid any problems
> from members with trap representation. I *think* that structure
> assignment *must* be done this way, or in some equivalent manner
> (except that padding bytes needn't be copied).
>
> It's common for some structure members to be meaningless depending on
> the values of other members.


That's a good point.

Can we therefore conclude that structure assignment cannot be done
as member-by-member assignments on systems that allow trap
representations, on the theory that assignment of a member having
a trap value incurs undefined behavior (or at least affects the overall
struct assignment operation)?

-drt

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      03-06-2006
"David R Tribble" <(E-Mail Removed)> writes:
> Micah Cowan <(E-Mail Removed)> writes:
>>> Except that the above text says that the value of a /member/ of the
>>> structure or union object may be a trap representation. It will have
>>> been read in the assignment, I should think.

>
> Keith Thompson wrote:
>> Not necessarily. Structure assignment *may* be done as if by calling
>> memcpy(), i.e., copying the raw bytes; this would avoid any problems
>> from members with trap representation. I *think* that structure
>> assignment *must* be done this way, or in some equivalent manner
>> (except that padding bytes needn't be copied).
>>
>> It's common for some structure members to be meaningless depending on
>> the values of other members.

>
> That's a good point.
>
> Can we therefore conclude that structure assignment cannot be done
> as member-by-member assignments on systems that allow trap
> representations, on the theory that assignment of a member having
> a trap value incurs undefined behavior (or at least affects the overall
> struct assignment operation)?


I think it means that the assignment can be done in any way the
implementation chooses, as long as any defined values of members in
the source are properly copied to the target, and as long as any
member trap representations in the source don't cause anything "bad"
to happen (defining "bad" is left as an exercise).

Accessing a trap representation invokes undefined behavior, but the
implementation is allowed to do so if it knows it won't cause any
problems.

The obvious way to do this is to use the equivalent of memcpy(). In
fact, it seems to me it would have been reasonable to *require* struct
assignment to be done as if by memcpy(). (An implemention might save
some time by not copying uninitialized members, but I doubt that any
real implementation actually does this; the time saved by not copying
padding bytes is unlikely to be significant.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
lawrence.jones@ugs.com
Guest
Posts: n/a
 
      03-06-2006
In comp.std.c David R Tribble <(E-Mail Removed)> wrote:
>
> Can we therefore conclude that structure assignment cannot be done
> as member-by-member assignments on systems that allow trap
> representations, on the theory that assignment of a member having
> a trap value incurs undefined behavior (or at least affects the overall
> struct assignment operation)?


No, because your theory doesn't necessarily hold. An implementation is
free to use member-by-member assignment if it knows, or can ensure, that
no untoward behavior will actually occur.

-Larry Jones

Some people just don't have inquisitive minds. -- Calvin
 
Reply With Quote
 
David R Tribble
Guest
Posts: n/a
 
      03-07-2006
[struct copy]

Keith Thompson wrote:
> [...]
> The obvious way to do this is to use the equivalent of memcpy(). In
> fact, it seems to me it would have been reasonable to *require* struct
> assignment to be done as if by memcpy(). (An implemention might save
> some time by not copying uninitialized members, but I doubt that any
> real implementation actually does this; the time saved by not copying
> padding bytes is unlikely to be significant.)


Pathological cases can be devised:

struct Foo
{
unsigned m1: 8;
unsigned :24;

unsigned m2: 8;
unsigned :24;

unsigned m3: 8;
unsigned :24;

unsigned m4: 8;
unsigned :24;
};

You could make the argument that copying only the first 8 bits of each
32-bit chunk of the structure could be faster than copying each entire
32-bit chunk.

-drt

 
Reply With Quote
 
WaterWalk
Guest
Posts: n/a
 
      03-09-2006

Keith Thompson wrote:
> Micah Cowan <(E-Mail Removed)> writes:
> > Keith Thompson <(E-Mail Removed)> writes:
> >> "Robin Haigh" <(E-Mail Removed)> writes:

> [...]
> >> > While on the subject, I'm not clear as to whether the above quote
> >> > answers a question I have. The question is: if we have an auto
> >> > struct, is it required that all members be initialised before the
> >> > struct can be copied by assignment? If not, where does it say
> >> > so?
> >>
> >> I think this is covered by the statement that the value of a structure
> >> or union object is never a trap representation. If there are no trap
> >> representations, there should be no problems with assignment.

> >
> > Except that the above text says that the value of a /member/ of the
> > structure or union object may be a trap representation. It will have
> > been read in the assignment, I should think.

>
> Not necessarily. Structure assignment *may* be done as if by calling
> memcpy(), i.e., copying the raw bytes; this would avoid any problems
> from members with trap representation. I *think* that structure
> assignment *must* be done this way, or in some equivalent manner
> (except that padding bytes needn't be copied).
>
> It's common for some structure members to be meaningless depending on
> the values of other members. For example:
>
> #include <stddef.h>
> int main(void)
> {
> #define MAX_LEN 42
> struct foo {
> int len;
> void *ptrs[MAX_LEN];
> };
>
> struct foo obj1, obj2;
> obj1.len = 1;
> obj1.ptrs[0] = NULL;
>
> obj2 = obj1;
> return 0;
> }
>
> Allowing structure assignment to be affected by member trap
> representations would cause the assignment to invoke undefined
> behavior.
>


Thanks for all the replies. Now I think I become more acquainted with
struct assignment.

I notice the term "trap representation" appears. I don't know exactly
what it means. Would you please give me some hints?

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-09-2006
"WaterWalk" <(E-Mail Removed)> writes:
[...]
> I notice the term "trap representation" appears. I don't know exactly
> what it means. Would you please give me some hints?


C99 6.2.6.1p5:

Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation and is read by an lvalue expression that does not
have character type, the behavior is undefined. If such a
representation is produced by a side effect that modifies all or
any part of the object by an lvalue expression that does not have
character type, the behavior is undefined. Such a representation
is called a _trap representation_.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Douglas A. Gwyn
Guest
Posts: n/a
 
      03-09-2006
Keith Thompson wrote:
> "WaterWalk" <(E-Mail Removed)> writes:
> > I notice the term "trap representation" appears. I don't know exactly
> > what it means. Would you please give me some hints?

> C99 6.2.6.1p5:
> Certain object representations need not represent a value of the
> object type. If the stored value of an object has such a
> representation and is read by an lvalue expression that does not
> have character type, the behavior is undefined. If such a
> representation is produced by a side effect that modifies all or
> any part of the object by an lvalue expression that does not have
> character type, the behavior is undefined. Such a representation
> is called a _trap representation_.


And the name is meant to suggest that the undefined behavior
might be as nasty as a hardware trap, although that actually
occurs only on relatively few platforms. The main thing is
that when a program produces a trap rep the C implementation
doesn't have to handle it "properly" (where "proper" describes
any of the behaviors a programmer might have been expecting).
For example, generated code might depend on a convention that
certain bits of the representation are always 0, so violating
that assumption causes incorrect computation.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-10-2006
Douglas A. Gwyn wrote:
> Keith Thompson wrote:
>
>>"WaterWalk" <(E-Mail Removed)> writes:
>>
>>>I notice the term "trap representation" appears. I don't know exactly
>>>what it means. Would you please give me some hints?

>>
>>C99 6.2.6.1p5:
>> Certain object representations need not represent a value of the
>> object type. If the stored value of an object has such a
>> representation and is read by an lvalue expression that does not
>> have character type, the behavior is undefined. If such a
>> representation is produced by a side effect that modifies all or
>> any part of the object by an lvalue expression that does not have
>> character type, the behavior is undefined. Such a representation
>> is called a _trap representation_.

>
>
> And the name is meant to suggest that the undefined behavior
> might be as nasty as a hardware trap, although that actually
> occurs only on relatively few platforms. The main thing is
> that when a program produces a trap rep the C implementation
> doesn't have to handle it "properly" (where "proper" describes
> any of the behaviors a programmer might have been expecting).
> For example, generated code might depend on a convention that
> certain bits of the representation are always 0, so violating
> that assumption causes incorrect computation.


Hardware traps aren't all that unusual. Many systems will
trap if given a `long*' with a few stray "low-order" one-bits.
Some IEEE floating-point systems will respond to "signalling"
operands by generating traps, although I'll grant that most C
implementations appear to prefer operating their IEEE units in
a non-trapping mode. VAX processors had/have a different F-P
scheme that traps on certain invalid operands.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
what is Deep Copy, shallow copy and bitwises copy.? saxenavaibhav17@gmail.com C++ 26 09-01-2006 09:37 PM
is dict.copy() a deep copy or a shallow copy Alex Python 2 09-05-2005 07:01 AM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM
implementing a templated struct within a templated struct RA Scheltema C++ 3 01-06-2004 11:25 AM



Advertisments