Can I determine the number of member of a Structure?

This is part of my UCSD homework. If anybody does not feel answering it, I am OK with it.

If I have a bunch of structures each with different amount of members of different type. Without looking inside the structure declaration, is it possible to have a function like this?

"int CountStructureMember (struct myStruc StructInQuestion) " where the return is an int representing the total count of the members.

1. be able to get the total count of the members.
2. find out the type of each member.
3. access each member without actually knowing what it is, just like an array where I could say X = array[12] which will access the 13th element.

The reason behind this question is this. Structure could be composed of int that is 4 bytes long, char which is 1 byte and long long which is 8 bytes. when those are entered in memory the professor told us that these:

1. Usually each members is stored in a 8 bytes long storage, then the next is stored after that and so on. but since an int is 4 bytes the next does not immediately follow the first instead a padding of zero is added to complete the 8 bytes before the next is added.

example the structure has these 3 members.

int X = 0x1234;
char Y = 'A';
long long Z = 0xabcdef12;

we are told that it gets stored in memory like this and I verified it already by dumping the memory and the professor is correct.

34 12 00 00 41 00 00 00 12 ef cd ab




However you lost 4 bytes!:)
long long occupies 8 bytes. So the result shall be

34 12 00 00 41 00 00 00 12 ef cd ab 00 00 00 00

As for your questions you can not know how many members and what their types there are in a structure.

closed account (zb0S216C)
There are too few bytes there to fully represent the structure; vlad seems to be forgetting that the size of a type depends on the implementation ("long long" doesn't always allocate 8-bytes). You're forgetting the alignment bytes inserted by the compiler which can increase the overall size. Note that the number of bytes inserted between two members is implementation-defined.

Wazzak
Last edited on
It's not possible, and moreover, your professor either oversimplified things or was wrong: the layout you're seeing is not because "each members is stored in a 8 bytes long storage".

It is because the alignment requirement of long long on your system is 8: the long long subobject can only be placed at an offset that's divisible by 8, so after filling in the 4-byte int and a 1-byte char, the compiler must skip 3 bytes until it gets to the offset 8, which is the first position where a long long could be placed.

case in point, add another char to your struct, right after the first one, and the size will not change.
I will have to agree with " Vlad from Moscow" that I missed 4 bytes in the type long long and I have to agree with "framework" that alignment bytes are inserted, but unless I misunderstood my professor those "00" are added to make the alignment correct.

anyway, "Vlad from Moscow" said that " As for your questions you can not know how many members and what their types there are in a structure. " do the other programmers concur with that statement? if this is the case then I would assume that Vlad meant that I should look and check each member of the structure to determine the type and the size.
closed account (zb0S216C)
mendozae wrote:
"As for your questions you can not know how many members and what their types there are in a structure. " do the other programmers concur with that statement?"

That statement doesn't even explicitly reference the size factor -- it simply means that the number of members and the types of those members may be unknown and thus, the size will be unknown. It does not state how the size of the members and the alignment padding affects the overall size.

The simple fact is, a compiler is free to re-arrange a structure's layout so that it runs efficiently on the target architecture. Because there's so many architectures and so many ways to re-arrange a structure, it's damn dear impossible to determine the final layout of a structure. However, if a compiler chooses to re-arrange a structure, it cannot affect the behaviour of the structure (accessing the structure, for instance).

In conclusion, the factors that influence the overall size of a structure are (and then some):

● Alignment padding
● CPU architecture
● The compiler
● Size requirements of a type
● Additional bytes for a virtual table (if needed)
● Packing options (packing a structure removes alignment padding)

Wazzak
Last edited on
do the other programmers concur with that statement?

Yes, at least until the proposal N3326 makes it into C++17 in some form

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3326.pdf
I am sure my professor will not give this assignment if he thinks it cannot be done. This is a portion of the assignment synopsis.

Assignment 7 THIS MUST BE A “C” PROGRAM not C++

The purpose of this exercise is to illustrate the endian conversion of arbitrary scalar objects within an 1 aggregate type, such as a structure or class. If it is arbitrarily assumed that a long is 4 bytes and a short 2 is 2 bytes, a structure defined and initialized as:

struct { long height; short width, depth; } box = {0x01234567L, 0x89ab, 0xcdef};

will appear in memory in one of the two following orders, dependent upon the machine's endian implementation. There can be an arbitrary amount of implementation-dependent padding after any member(s) of the structure:

Big Endian Little Endian
First byte in memory: 01 67
45 14
45 23
67 01
----- possible compiler padding here -----
89 ab
ab 89
----- possible compiler padding here -----
cd ef
ef cd
----- possible compiler padding here -----


1. By looking on the comment "vlad From moscow" and "cubbi" appears to imply that I just need to know a little bit more on how members are stored in memory but it can be done.

2. On the other hand "Framework" appears to imply that unless I know how the compiler does the padding, CPU architecture, the compiler. This assignment is almost near impossible to accomplish.

SO: I would assume that my best solution is to tell my professor as per program written and executed in my laptop and Visual Studio ver 10 this is my program. If this is the case I can expect a zero in this because as far as he is concerned all our code should be transportable to another system.

do the other programmers concur with that statement?

Never ever at least is this life. All that programmers could know in runtime (you said you need function for different structures, then we talk about runtime)

only that fact that stack is filled to sizeof(struct myStruc) (or even little bit more, coz stack is padded itself) and all things like alignment and padding are known in compile time only...

But!!! If you are allowed to do in design time and call some precompiled builtins/macroses which your compiler could support - it could be case.
And of course after compilation on different systems it may return different results.

I don't know how to enumerate structures in design-time (at least guess it's impossible in gcc), but for one (with known at design time name) you could create a set of functions smth like

1
2
3
4
5
6
#pragma pack(push[,n])
int FFF_n()
{
  return sizeof(MyStructure);
}
#pragma pack(pop) 

and in your main function begin to manipulate with results of FFF_n() (and it will probably not work too if in header structure explicitly repacked) with different n. All of the those stuff are rather dirty hacks and shouldn't be considered as solution of this problem. I just want to say that it might be job for cool precompiler.
Assignment 7...----- possible compiler padding here -----

That quoted text is correct: given those specific assumptions, the layouts of that particular structure on a big-endian and on a little-endian systems are indeed as shown.

But this is not related to the initial question
Without looking inside the structure declaration, is it possible to ... return is an int representing the total count of the members.

That can't be done as stated: given "01 45 45 67 89 ab cd ef", there is no way to tell, without looking inside the structure declaration, whether you're dealing with a struct {char c1, c2, c3, c4, c5, c6, c7, c8;} and the function should return 8 or with a struct {long long n;} and the function should return 1.
It appears I do not have any choice, but I have to look inside the structure.
Now I have this structure and have assign values to it. It looks so simple but I fail to convert big endians to little endians and vice versa. I tried shifting the bits to the left but it would not take this instruction
head >> (8 * sizeof(bytes) & 0xffffffff; compiler error
I search the web but no luck..HELP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
struct Test 
{ 
    float flt; 
    double dbl; 
    void *vp; 
};
void reverseStructure(struct Test fp);
int main()
{  
    struct Test x = { 23.6F, -425e-6, (void *)0x2345};  
    return (0);
} 

void reverseStructure(struct Test fp)
{ 
   char *head = (char*) &fp; 

   return;
}
Topic archived. No new replies allowed.