Is there a way to assign values to myS without referring to s1, s2, ..., sn explicitly, i.e., instead of

Code:

myS.s1 = v1;
myS.s2 = v2;
//...
myS.sn = vn;

is something like

Code:

for (int i=1; i<=n; i++) {
/* Do something like myS.i = vi */
}

possible? Thanks!

04-10-2009

laserlight

Use an array or a container like std::vector instead of n separate member variables.

04-10-2009

neandrake

So is it correct to say that there is no way to enumerate over member variables in a struct, likewise in a class? The only way I could think of would be to access via pointers, but you would have to know the size of individual members. Are you guaranteed a correct layout from a C/C++ compiler in order for this to work?

edit: By "correct layout" I mean are you guaranteed the order of members to be the same as defined?

04-10-2009

neandrake

Followup:

It looks like you are guaranteed the order of members defined in a struct, however the compiler may need to pad fields, depending on architecture. There is probably no good way to do this.

True, although 99.9% of the programmers ignore this fact completely. How often haven't I seen fread(&file_header, 1, sizeof(file_header), some_file_type_handle);

So it's generally ignored completely.

04-10-2009

matsp

Quote:

Originally Posted by EVOEx

True, although 99.9% of the programmers ignore this fact completely. How often haven't I seen fread(&file_header, 1, sizeof(file_header), some_file_type_handle);

So it's generally ignored completely.

But for portable code, you can almost guarantee that the header is carefully constructed in such a way that it is unlikely to have any (unknown) gaps in it - either by asking the compiler to not add gaps, or by arranging the content in such a way that in almost all compilers the data is aligned properly no matter what compiler/processor architecture it is.

Or the code is written such that it reads each element at a time.

Also, as long as all elements in a struct are the same type (or a set of members are the same type and consecutive elements), you could use a pointer to that type - it should increment the same way as a pointer as the compiler arranges the elements. But if you have more than three of something, it's likely that you actually WANT an array anyways.

--
Mats

04-10-2009

medievalelks

What are you trying to accomplish with this?

04-10-2009

adeyblue

Quote:

Originally Posted by slippy

is something like

Code:

for (int i=1; i<=n; i++) {
/* Do something like myS.i = vi */
}

possible? Thanks!

It's technically possible given the struct in the OP, and ones like it.

So it can be done, but it is has a limited applicability given the stringent requirements on naming / initialization etc and the amount of manual bookkeeping you have to contend with. Use an array or vector for a much easier life.

04-10-2009

grumpy

Quote:

Originally Posted by neandrake

It looks like you are guaranteed the order of members defined in a struct,

In C++, that's only true for PoD struct types. For non-PoD types (which includes, among other things, structs with a declared destructor or a virtual function) the order is not guaranteed.

Add to that the padding in structs, and the implementation defined layout of basic types (int, double, enums, pointers, etc) and it is usually better to write code that does not rely on specific layout of types in memory, if you care at all about portability.

04-10-2009

neandrake

The only thing I could see where you would want to guarantee the layout would be in microchips -- in which you should know the architecture very well. Even then you would probably doing a lot of stuff in assembly if it really mattered.