2 questions about struct copy

F

Flash Gordon

P said:
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.
 
D

David R Tribble

Keith said:
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
 
K

Keith Thompson

David R Tribble said:
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.)
 
L

lawrence.jones

In comp.std.c David R Tribble said:
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
 
D

David R Tribble

[struct copy]

Keith said:
[...]
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
 
W

WaterWalk

Keith said:
Micah Cowan said:
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?
 
K

Keith Thompson

WaterWalk said:
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_.
 
D

Douglas A. Gwyn

Keith said:
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.
 
E

Eric Sosman

Douglas said:
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.
 

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

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top