Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

C: Assigning structures

Name: Anonymous 2010-07-24 2:09

suppose we have the following type:

typedef struct {
    int bar;
    int baz;
    int foo;
} Something;


In order to do a copy, I usually do something like:

Something a, b;
...
memcpy ((void *) &a, (const void *) &b, sizeof(Something));

But also the following is legal (and far more quick to write).

Something a, b;
...
a = b;

Is there any disadvantage in doing the second one?

Name: Anonymous 2010-07-24 2:16

>>1
no, there isn't.
also, in case you didn't know... instead of this:
Something a;
a.bar = ...;
a.baz = ...;
a.foo = ...;

you can do this:
[code]Something a = { .bar = ..., .baz = ..., .foo = ... };

Name: Anonymous 2010-07-24 2:28

>>2
Thanks!

Name: Anonymous 2010-07-24 5:19

>>2
a = { .bar = ...
Is that C99?

Name: Anonymous 2010-07-24 5:31

>>4
If you want to check it just try doing it and compiling with

gcc -std=c99 -Wall -pedantic

Then let us know.

Name: Anonymous 2010-07-24 5:34

>>4
yes, it is.

Name: Anonymous 2010-07-24 5:49

>>5
I really don't think that's what he meant.

Name: Anonymous 2010-07-24 10:01

>>7
Oh, I see, so I have misunderstood the question. How frightfully careless of me.
>>4
No, that is a line of text on my monitor.

Name: Anonymous 2010-07-24 10:12

>>8
Yeah, fucko, you best apologise!

Name: Anonymous 2010-07-24 12:16

>>9
You don't fuck with Xarn, boy.

Name: Anonymous 2010-07-24 12:20

>>10
You forgot your BBCode, Xarn Fan.

Name: Anonymous 2010-07-25 17:28

>>2
Is there something analog to a struct pointed by a pointer?
e.g.:
typedef struct {
    int bar;
    int baz;
    int foo;
} Something;

Something * pSomething;
pSomething = { ->bar = ..., ->baz = ..., ->foo =...};

Name: Anonymous 2010-07-25 17:45

>>12
[code] tags, you fuckface.

Also, it's ``analogous''.

Name: Anonymous 2010-07-25 17:48

>>12
No, because where an uninitialised pointer points to is unspecified, so you could be attempting to assign to anywhere.
Also by saying pSomething = { ... you're immediately saying "assign the value of this pointer to somewhere else" so it won't be modifying the memory it previously pointed to.
The best analogue for what you want is:

Something anus = { .bar = 1, .baz = 2, .foo = 3 }; /* temporary */
Something *finger;
/* On the stack: */
finger = &anus;
/* On the heap: */
finger = malloc (sizeof (Something));
*finger = anus;

Name: Anonymous 2010-07-25 17:59

>>1
The compiler may emit a series of fast machine word (or other type) moves for the latter case, while the former certainly cannot be optimized like this.

Name: Anonymous 2010-07-26 0:03

>>1
Don't write it that way.  Write it this way:

memcpy(&a, &b, sizeof(a));

These days, "memcpy" and "=" will give you the same damn assembly, except "=" is much less prone to typos.

Name: Anonymous 2010-07-26 3:48

>>16
I wonder, = might allow better optimizations, since the compiler knows what it means.

Name: Anonymous 2010-07-26 4:30

>>17
If your compiler doesn't know what memcpy means, then your compiler is a backwards piece of shit.  GCC emits the same exact damn code in both cases (go check the assembler!) even with optimizations turned off.  You should go take a class on compiler design, it'll clear up some misconceptions about optimization.

Name: Anonymous 2010-07-26 9:12

>>17
To put what >>18 is saying more clearly, memcpy is part of the C standard library. The compiler ought to be able to optimize it just as well because its semantics are standardized. (A problem occurs, however, when you apply this logic to something like malloc.)

Name: Anonymous 2010-07-27 9:33

>>19
What problem occurs?

Name: Anonymous 2010-07-27 9:48

This thread has been closed and replaced with the following:
Name: Anonymous
Email:
Subject: Applying memcpy logic to malloc

Message: It doesn't work.

Name: Anonymous 2010-07-27 10:18

>>21
Now listen here jerkface!

Name: Anonymous 2010-07-27 10:32

>>19
There are some optimizations regarding malloc -- some compilers take into account that the object referred to by the result of a malloc does not have any alias.

Name: Anonymous 2010-07-27 11:25

>>19

#include <stdio.h>

void * memcpy(void * destination, const void * source, size_t num)
{
    return "CPY MY MEM";
}

int main()
{
    printf("%s\n", (char*)memcpy("HAXUS", "THE REIMPLEMENTOR", 0));
    printf("%s\n", (char*)memcpy("HAXUS", "THE REIMPLEMENTOR", 1));
    return 0;
}

Can you guess the results?

$ gcc -dumpversion
3.4.6
$ gcc test.c -Wall -pedantic -ansi
$ ./a.out
HAXUS
CPY MY MEM

Funny, ain't she?

Name: Anonymous 2010-07-27 13:42

>>24
I DEMAND AN EXPLANATION FOR THIS WITCHERY

Name: Anonymous 2010-07-27 13:55

>>25

He appears to have haxus'd the axis and flipped our scripts, sir.

Name: Anonymous 2010-07-27 14:11

>>1
>>16,18-san is correct. As far as I know, all compilers with even rudimentary optimization will emit the same machine code. Also, get into the habit of using sizeof on the variable (dereferenced if it's a pointer), not the type, in case the type needs to be changed.

As far as which is better... it depends.

memcpy is potentially more error prone; it does not require that the given types are the same, so you could run into problems when you try to change one of the types and the compiler doesn't raise an error. memcpy is also more verbose, though you can easily use a move macro.

But I personally don't like using = with structs that aren't value types because it implies copy semantics (especially to anyone with C++ experience.) memcpy makes it obvious that it is strictly a bitwise move, the original should be discarded. For simple structs like struct point {float x, y;}; however I'll use = because it's a transparent value type.

Name: Anonymous 2010-07-27 14:15

http://codepad.org/E4yvlIEN
memcpy2 shows both

Name: Anonymous 2010-07-27 14:19

>>28
Well, yeah. It's not overloading a stdlib function like in >>24.

Name: Anonymous 2010-07-27 14:50

>>24
The most surprising thing about that example is someone considered it an optimization worth implementing. Is that a common pattern in machine-generated code?

Name: Anonymous 2010-07-27 14:52

>>20
I'll be nice. malloc leaves too much up to the imaginationimplementation. To keep this post short, memcpy is stateless but malloc is stateful by design. The nature of that operating state is of interest to malloc implementers and you just can't have your compiler go about fucking with that. Also, see >>24.

Name: Anonymous 2010-07-27 14:56

>>30
memcpy is a commonly used function, and it really can do with optimization in places. It's not all about assignments between structures. (I have no idea whether GCC is smart enough to catch many of the interesting/non-assignable cases though.)

Name: Anonymous 2010-07-27 15:45

>>32
memcpy is a commonly used function
No shit. But how often is memcpy used with a constant size argument of zero? That's the optimization.

Name: Anonymous 2010-07-27 16:22

>>33
I was referring to memcpy as a generally optimized call. If you want to focus on the case where the size is zero, that is cause for surprise. I'm sure this case probably comes up organically in C++ for some stupid reason.

Name: Anonymous 2010-07-27 17:29

Grr... I can't come up with some scheme to make GCC handle memcpy and = differently when optimizations are enabled.  Not even volatile helped ...

Name: Anonymous 2010-07-27 18:02

>>35
Try -O-3 for negative optimisations

Name: Anonymous 2010-07-27 18:45

>>36
Nah, -O0 is enough.

Name: Anonymous 2010-07-28 14:47

>>35
Why would you want to do this?

Anyway it should be trivial. Write your own mymemcpy() and #define memcpy mymemcpy

Name: Anonymous 2010-07-28 14:48

Bah, didn't want to sage (since this thread is actually about programming)

Name: Anonymous 2010-07-28 14:58

>>38
I want it to use the builtin memcpy, otherwise it's pointless.  I suppose I'll have to dig through the sources.

>>39
Reported for bumping.

Name: Anonymous 2010-07-28 15:00

>>35
void (*mymemcpy)(void *, const void *, size_t) = &memcpy; and then use mymemcpy instead of memcpy.

Name: Anonymous 2010-07-28 15:07

>>35
Oh yeah, and don't forget -fno-strict-aliasing. Fucking gcc developers.

Name: Anonymous 2010-07-28 15:18

/* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
   a call to __builtin_memcpy.  */


I think that's it.

Name: Anonymous 2010-07-28 17:46

memecpy

Name: Anonymous 2010-07-28 18:09

>>44
I lol'd.  Well, I couldn't help it.

Name: Anonymous 2010-07-28 18:36

>>35,40
I can't come up with some scheme to make GCC handle memcpy and = differently
I want it to use the builtin memcpy, otherwise it's pointless.
Are you listening to yourself? Have you not read a single thing anyone else is saying? They're the same goddamn thing. The built-in memcpy() is not even a real function call. They can't behave differently because by definition they do the same thing.

You're not making any sense.

Name: Anonymous 2010-07-28 18:42

>>46
Feel free to discuss how fnop and nop differ also.

Name: Anonymous 2010-07-28 19:16

>>46
They can't behave differently because by definition they do the same thing.
Correct, I looked that up in the source code for GCC (>>43).  I had expected memcpy to be transformed into an assignment, but it was the other way around.

Name: Anonymous 2010-07-28 20:02

>>48
Well duh it's the other way around. All assignments can be transformed into memcpy, but not all memcpy can be transformed into assignments.

Name: Anonymous 2010-07-28 20:04

>>49
Erm, well excuse me.  Meant to say "struct assignments".  Obviously FP->integer assignments and such can't be turned into memcpy.

Name: Anonymous 2010-07-28 20:04

>>49
Actually, just imagine a memcpy of arbitrary size transforming into a struct assignment of the same size.

Name: Anonymous 2011-02-03 3:53


Don't change these.
Name: Email:
Entire Thread Thread List