lppier
lppier

Reputation: 1987

C Struct Order of Members

I'm taking over a piece of code..c programming in linux. I did a small change to a struct

typedef struct {
  unsigned int a1;
  ..
  ..
  ..
  float f1;
  unsigned int a2;
  unsigned int a3;

  unsigned int offending; // shifted this
} test;

I shifted unsigned int offending to before float f1, like this:

typedef struct {
  unsigned int a1;
  ..
  ..
  ..
  unsigned int offending;
  float f1;
  unsigned int a2;
  unsigned int a3;


} test;

and the code crashes... what could be the problem?

Is the order of members of a c struct important?

Upvotes: 0

Views: 402

Answers (2)

david.pfx
david.pfx

Reputation: 10863

What could be the problem? Depend on the rest of the code, and what else you did.

No, the order of members of a struct is not intrinsically important. It is made so when other code depends on it.

Possible causes (not exhaustive):

  • You didn't recompile everything and there is external linkage on this struct or some aspect of it.
  • By moving the member you changed the alignment of other members and/or the sizeof() the struct, and didn't compensate for that.
  • There is a literal constant or macro somewhere with a size or offset that depends on this struct.
  • There is faulty code which never failed before but does now because of a change in memory layout.
  • The struct is used somewhere as part of another struct or union, and the problem is related to that.
  • There is a list initialisation using {} that no longer matches the member order.

You really should provide details of how it crashes. Otherwise it guesswork. And perhaps even then.

edit: ht @Jens.

Upvotes: 3

Jens Gustedt
Jens Gustedt

Reputation: 79003

The most probable reason for crashes if you change data layout is initialization. If you have old-time initializers in your code that use declaration order, all of a sudden the fields will receive different values than before. Therefore modern C since C99 has designated initializers that avoid that problem:

test toto = { 32, ... , 42, };                    // sensible to reordering
test tata = { .a1 = 32, ... , .offending = 42, }; // still the same

Upvotes: 1

Related Questions