423,095 Members | 2,030 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 423,095 IT Pros & Developers. It's quick & easy.

structures --assignment?

P: n/a
Hi there,
I've got a simple (newbee)-question.
Is the following thing right?

struct x {
int a;
int b;
}
...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1

I think there is something in the FAQ, but
I'm not sure if I took it right. The above
code works with the compiler I'm using, but
I'm sure if this kind of statement is allowed.
Thanks for any help
Michael

Nov 14 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
"Michael" <mi****@gmx.net> wrote in message
news:bu**********@rzcomm2.rz.tu-bs.de...
struct x {
int a;
int b;
} ; /* Don't forget :) */ ...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1


Yes, structure assignment is fine. But if you have pointers in the struct,
you might need to make copies of the data pointed to (a so-called "deep
copy"). (An alternative is reference counting, but that's a bit more
complicated.)
Nov 14 '05 #2

P: n/a
Michael <mi****@gmx.net> wrote:
Is the following thing right?

struct x test1;
struct x test2;

test2 = test1


Sure, perfectly correct.

Note, though, that it is not specified whether the copying is done
bytewise or per member; if the struct contains padding, then
memcmp(&test1, &test2, sizeof test1) may or may not succeed depending on
your implementation. All individual members will compare equal, though.

Richard
Nov 14 '05 #3

P: n/a
Hey,
thank you for the fast answers. So I don't
bother anymore.

@Alex: Mea culpa, but whew the code wasn't taken
out of some program ;-)

Have a nice day
Michael
Nov 14 '05 #4

P: n/a
Michael wrote:

Hi there,
I've got a simple (newbee)-question.
Is the following thing right?

struct x {
int a;
int b;
}
...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1

I think there is something in the FAQ, but
I'm not sure if I took it right. The above
code works with the compiler I'm using, but
I'm sure if this kind of statement is allowed.


It's allowed. What you can't do however,
is compare structures by operators.

test2 == test1
test2 != test1

--
pete
Nov 14 '05 #5

P: n/a
Michael wrote:
Hi there,
I've got a simple (newbee)-question.
Is the following thing right?

struct x {
int a;
int b;
} ^^^^^
No, you are missing a semicolon.
...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1

^^^^^
No, you are missing another semicolon.

--
Martin Ambuhl
Nov 14 '05 #6

P: n/a
Michael wrote:


Is the following thing right?

struct x {
int a;
int b;
};
// ...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1


Bad idea. Try

x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}

const struct x test1 = x_create(17, 33);
const struct x test2 = test1;

Try to avoid uninitialized objects.
Try to avoid variables if possible.
Define constants instead.

Nov 14 '05 #7

P: n/a

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:40**************@jpl.nasa.gov...
Michael wrote:


Is the following thing right?

struct x {
int a;
int b;
};
// ...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1
Bad idea. Try

x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}


How is this a good idea? "result" is in the scope of the function only and
UNDEFINED elsewhere.
const struct x test1 = x_create(17, 33);


This is not valid.

<snip rest>

Tom
Nov 14 '05 #8

P: n/a

On Fri, 23 Jan 2004, Tom St Denis wrote:
Bad idea. Try

x x_create(int a, int b) {
struct x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}


How is this a good idea? "result" is in the scope of the function only and
UNDEFINED elsewhere.


So? Are you somwhow going to access "result" after the function returns?
Nov 14 '05 #9

P: n/a
Tom St Denis wrote:
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:40**************@jpl.nasa.gov...
Michael wrote:


Is the following thing right?

struct x {
int a;
int b;
};
// ...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1


Bad idea. Try

x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}

How is this a good idea? "result" is in the scope of the function only and
UNDEFINED elsewhere.

const struct x test1 = x_create(17, 33);

This is not valid.


On the contrary, it's fine. Your point about scope has no more force
against the example above, with return of a struct, than it would have
against the following (pointless but valid) code:

int set_int (int val)
{
int i = val;
return i;
}

int j = set_int(10);

That is, the variable i falls out of scope when set_int() returns, but
its value is nonetheless successfully transfered to j.

--
Allin Cottrell
Department of Economics
Wake Forest University, NC

Nov 14 '05 #10

P: n/a
Jarno A Wuolijoki wrote:
Tom St Denis wrote:
Bad idea. Try
struct x x_create(int a, int b) { struct x result;
result.a = a;
result.b = b;
return result;
}
How is this a good idea?
"result" is in the scope of the function only
and UNDEFINED elsewhere.


Are you somehow going to access "result" after the function returns?


I'm using it like this:

const struct x test1 = x_create(17, 33);

You really need to appreciate the *magic*
of a good optimizing C compiler here.

The C compiler reserves automatic storage for test1
then calls x_create passing a pointer to test1
(typically as a [hidden] first argument) to x_create.
In effect, the compiler calls:

x_create(&test1, 17, 33);

in this case.

The C compiler recognizes result as a reference to the return value:

struct x* x_create(struct x* pReturnValue, int a, int b) {
pReturnValue->a = a;
pReturnValue->b = b;
return pReturnValue;
}

so that x_create actually initializes test1 directly!

In fact, using my GNU C compiler, I can define

struct x* x_create(struct x*, int, int);

as an external function in another file then declare

extern struct x x_create(int a, int b);

and invoke

const struct x test1 = x_create(17, 13);

in my main program and test1 is initialized as expected.

Most modern C compilers implement this optimization.

Nov 14 '05 #11

P: n/a


E. Robert Tisdale wrote:

[ Much Snipped ]

Most modern C compilers implement this optimization.


"most" is not a number. (NAN) ...

And what if the compiler you have to work with
tomorrow is an ancient one which was used to generate
the code for "Rover?"

What will it do with those constructs?

What code will it actually generate?

"Undefined Behavior" comes to mind as a probable result.

Resident Skeptic and Professional Paranoid.

--
"It is impossible to make anything foolproof because fools are so
ingenious" - A. Bloch

Nov 14 '05 #12

P: n/a

"Jarno A Wuolijoki" <jw******@cs.Helsinki.FI> wrote in message
news:Pi**************************************@melk inpaasi.cs.Helsinki.FI...

On Fri, 23 Jan 2004, Tom St Denis wrote:
Bad idea. Try

x x_create(int a, int b) {
struct x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}


How is this a good idea? "result" is in the scope of the function only and UNDEFINED elsewhere.


So? Are you somwhow going to access "result" after the function returns?


Oh shit I guess you can do this. Hmm, I don't normally pass structures [or
return them] as arguments. Just doesn't seem right for C.

Tom
Nov 14 '05 #13

P: n/a
Tom St Denis wrote:
Oh shit. I guess you can do this.
Hmm, I don't normally pass structures [or return them] as arguments.
Just doesn't seem right for C.


According to Brian W. Kernighan and Dennis M. Ritchie,
"The C Programming Language" (1978), Chapter 6: Structures,
Subsection 2: Structures and Functions, page 121:

"There are a number of restrictions on C structures.
The essential rules are that the only operations
that you can perform on a structure are
take its address with &, and access one of its members.
This implies that
structures may not be assigned to or copied as a unit.
and that they can not be passed to or returned from functions.
(These restrictions will be removed in forth-coming versions.)"

Indeed, these restrictions have long since been removed.
You just haven't kept up with the C language.

Nov 14 '05 #14

P: n/a
On Thu, 22 Jan 2004 14:08:22 -0800, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote in comp.lang.c:
Michael wrote:


Is the following thing right?

struct x {
int a;
int b;
};
// ...

struct x test1;
struct x test2;
[.. init test1 somehow]

test2 = test1
Bad idea. Try


Good idea. Perfectly well defined C. All members of test2 will
compare identical to test1.
x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}

const struct x test1 = x_create(17, 33);
const struct x test2 = test1;
Idiotic, unless your structure points to dynamic memory and you need
to do a deep, rather than shallow, copy. And for that your sample
code would do a shallow copy as well.
Try to avoid uninitialized objects.
Where in the OP's post did he make use of an indeterminate object?
Try to avoid variables if possible.
Read the line you wrote above over and over again until you finally
see its absurdity.
Define constants instead.


Instead of what?

--
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++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #15

P: n/a
Hi there,
as I already stated I'm not an expert in C.
After reading my post again I have to admit
that I didn't point out exactly the things
I want to know. But most of you anticipate
the right thing, not the missing colons but
the structure-assignment :-)
Ok, so far I get a lot of answers, thanks for that.

I'm I right that
a) The assignment is legal, but to do it by function
is somehow more flexible e.g. a deep copy can be done
b) If I use structs itself not pointers (return-value),
well I think I do the same thing. <struct> = <struct>
Am I wrong?
I think I shouldn't care about the way the compiler
do it, if the statement itself is legal.(?)

Regards
Michael

Jack Klein schrieb:
Nov 14 '05 #16

P: n/a
On Fri, 23 Jan 2004 01:08:05 GMT, "Tom St Denis" <to********@iahu.ca>
wrote:

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:40**************@jpl.nasa.gov...
Michael wrote:
>
>
> Is the following thing right?
>
> struct x {
> int a;
> int b;
> };
> // ...
>
> struct x test1;
> struct x test2;
> [.. init test1 somehow]
>
> test2 = test1
Bad idea. Try

x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
}


How is this a good idea? "result" is in the scope of the function only and
UNDEFINED elsewhere.


While what you say is true for all automatic variables local to the
function, it is not true for the value. If the function were declared
to return an int and the return statement specified result.a, you
would not see a problem even though result.a cannot exist if result
does not.

While it is unusual (or better unpopular) to pass and return structs
as opposed to pointers to structs (because of additional resource
consumption), it is legal. Unlike attempts to return arrays,
returning a struct really returns the complete aggregate value of the
struct, not a pointer to an object which might no longer exist.
const struct x test1 = x_create(17, 33);
This is not valid.


Worked fine on my system.

<snip rest>

Tom


<<Remove the del for email>>
Nov 14 '05 #17

P: n/a
On Thu, 22 Jan 2004 18:54:55 -0800, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote:
Jarno A Wuolijoki wrote:
Tom St Denis wrote:
Bad idea. Try
struct x x_create(int a, int b) {
struct x result;
result.a = a;
result.b = b;
return result;
} How is this a good idea?
"result" is in the scope of the function only
and UNDEFINED elsewhere.


Are you somehow going to access "result" after the function returns?


I'm using it like this:

const struct x test1 = x_create(17, 33);

You really need to appreciate the *magic*
of a good optimizing C compiler here.

The C compiler reserves automatic storage for test1
then calls x_create passing a pointer to test1
(typically as a [hidden] first argument) to x_create.
In effect, the compiler calls:

x_create(&test1, 17, 33);


This is utter hogwash. The called function has no idea how the
returned value will be used. It simply returns the value, an
aggregate value in this case, using whatever convention the compiler
writer chooses to establish, and code in the calling program does
whatever is appropriate with this value.

in this case.

The C compiler recognizes result as a reference to the return value:
C does not pass by reference, period.

struct x* x_create(struct x* pReturnValue, int a, int b) {
pReturnValue->a = a;
pReturnValue->b = b;
return pReturnValue;
}

so that x_create actually initializes test1 directly!
Completely irrelevant to your previous discussion.

In fact, using my GNU C compiler, I can define

struct x* x_create(struct x*, int, int);

as an external function in another file then declare

extern struct x x_create(int a, int b);

and invoke

const struct x test1 = x_create(17, 13);

in my main program and test1 is initialized as expected.

Most modern C compilers implement this optimization.


More drivel.
<<Remove the del for email>>
Nov 14 '05 #18

P: n/a
On Fri, 23 Jan 2004 09:36:08 +0100, Michael <mi****@gmx.net> wrote:
Hi there,
as I already stated I'm not an expert in C.
After reading my post again I have to admit
that I didn't point out exactly the things
I want to know. But most of you anticipate
the right thing, not the missing colons but
the structure-assignment :-)
Ok, so far I get a lot of answers, thanks for that.

I'm I right that
a) The assignment is legal, but to do it by function
is somehow more flexible e.g. a deep copy can be done
Your first clause is correct. Everything after the comma is the
result of being sucked in by a troll and can be safely ignored.
b) If I use structs itself not pointers (return-value),
well I think I do the same thing. <struct> = <struct>
Am I wrong?
No, you are correct. A function can return a struct (actually the
aggregate value of the struct) which can then be used almost
everywhere an actual struct object could be used.

Since it is legal to say
struct_obj1 = struct_obj2;
it is also legal to say
struct_obj1 = function_returning_struct_obj(...);

Since it is legal to say
struct_obj1.member1 = struct_obj2.member1;
it is also legal to say
struct_obj1.member1 = function_returning_struct_obj(...).member1;
I think I shouldn't care about the way the compiler
do it, if the statement itself is legal.(?)


Probably true. Definitely true until you are much more experienced
and write code where performance is almost as important as
correctness.
<<Remove the del for email>>
Nov 14 '05 #19

P: n/a
In article <40**************@jpl.nasa.gov> E.**************@jpl.nasa.gov writes:
Jarno A Wuolijoki wrote: .... In fact, using my GNU C compiler, I can define

struct x* x_create(struct x*, int, int);

as an external function in another file then declare

extern struct x x_create(int a, int b);

and invoke

const struct x test1 = x_create(17, 13);

in my main program and test1 is initialized as expected.

Most modern C compilers implement this optimization.


There are modern C compilers that optimise still better and return
small enough structs through the registers.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #20

P: n/a
Dik T. Winter wrote:
There are modern C compilers that optimize still better and return
small enough structs through the registers.


Which C compiler?

How large a structure can it return in registers?
What does it do with larger structures?

Nov 14 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.