sizeof a relative pointer in a struct

M

ManicQin

Hi all.
I'm trying to get the size of a variable in a struct by his relative
postion i.e.

///
#define offsetof(s,m) (size_t)&(((s *)0)->m)

struct ThePimp{
char rings[10];
char blings[20];

};

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );

///
(If I have any syntax mistakes please ignore)

You can easily predict that sizeOfBling will be 4... (sizeof(int*))
Is there any way to acomplish it?

Thanks
 
N

Noob

ManicQin said:
#define offsetof(s,m) (size_t)&(((s *)0)->m)

AFAIU, however offsetof is defined, it is defined in stddef.h

$ cat foo.c
#include <stdio.h> /* printf */
#include <stddef.h> /* offsetof */
struct ThePimp { char rings[10]; char blings[20]; };
int main(void)
{
printf("%d\n", (int)offsetof(struct ThePimp, blings));
return 0;
}

$ gcc -std=c89 -pedantic -Wall -Wextra foo.c

$ ./a.out
10
 
R

REH

Hi all.
I'm trying to get the size of a variable in a struct by his relative
postion i.e.

///
#define offsetof(s,m) (size_t)&(((s *)0)->m)

struct ThePimp{
char rings[10];
char blings[20];

};

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );

///
(If I have any syntax mistakes please ignore)

You can easily predict that sizeOfBling will be 4... (sizeof(int*))
Is there any way to acomplish it?

Thanks

1. offsetof is already defined for you.
2. why not just use sizeof?
3. Where does the "easily predicted" 4 come from?
4. How does your method adjust for alignment?

REH
 
K

Keith Thompson

ManicQin said:
I'm trying to get the size of a variable in a struct by his relative
postion i.e.

///
#define offsetof(s,m) (size_t)&(((s *)0)->m)

struct ThePimp{
char rings[10];
char blings[20];

};

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );

///
(If I have any syntax mistakes please ignore)

You can easily predict that sizeOfBling will be 4... (sizeof(int*))
Is there any way to acomplish it?

I can't think of any way to determine the size of a member of a
structure using offsetof. You might think you can determine a
member's size by subtracting its offset from the offset of the
following member, but there could be padding.

The way to determine the size of something is to use sizeof. The only
reason to use something else is to satisfy the requirements of a bad
homework assignment. In this case, you can't apply sizeof to the
member itself given just the type, but if you have an object or
expression of type "struct ThePimp" you can apply sizeof to a member
of that object or expression.

I have a more specific method in mind, but I'm not going to post it
because I don't want to do your homework for you.
 
R

rpgfan3233

Hi all.
I'm trying to get the size of a variable in a struct by his relative
postion i.e.
///
#define offsetof(s,m)   (size_t)&(((s *)0)->m)
struct ThePimp{
char rings[10];
char blings[20];

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );
///
(If I have any syntax mistakes please ignore)
You can easily predict that sizeOfBling will be 4... (sizeof(int*))
Is there any way to acomplish it?

1. offsetof is already defined for you.
2. why not just use sizeof?
3. Where does the "easily predicted" 4 come from?
4. How does your method adjust for alignment?

REH

The "easily predicted" 4 comes from a machine where sizeof(TYPE*) = 4
because it is the native size for that machine (most likely a 32-bit
machine).
 
M

Martin Ambuhl

I am reposting the reply I made in <
> Hi all.
> I'm trying to get the size of a variable in a struct by his relative
> postion i.e.

That's the wrong way.

It's even more wrong if you need to define offsetof:
> #define offsetof(s,m) (size_t)&(((s *)0)->m)
> struct ThePimp{
> char rings[10];
> char blings[20];
> };
> int sizeOfBling = sizeof( (*char)&ThePimp +
> (char)offsetof(ThePimp,blings) );

If you have an instance of the struct, you can get the sizea
immediately. Obviously your code is meaningless, since ThePimp is a
struct tag and trying to take the address of a struct tag is just silly.
> (If I have any syntax mistakes please ignore)

How can we?

> You can easily predict that sizeOfBling will be 4... (sizeof(int*))

No, I cannot. rings and blings are arrays of chars, not pointers to
int. Their sizes are _not_ sizeof (int *). (And sizeof(int *) is by no
means assured to be 4).
> Is there any way to acomplish it?

Consider the following program. Is there anything you need (other than
a completely spurious claim that a char array is a pointer-to-int) that
it does not give?

#include <stdio.h>
#include <stddef.h>

struct ThePimp
{
char rings[10];
char blings[20];
};

int main(void)
{
struct ThePimp pimpinstance;

printf("For this implementation,\n"
"The size of a struct ThePimp is %zu\n"
"and the size of an instance of it is %zu.\n"
"The size of the rings array member is %zu,\n"
" and it has %zu elements.\n"
"The size of the blings array member is %zu,\n"
" and it has %zu elements.\n\n"
"The offset of the rings array member is %zu;\n"
"The offset of the blings array member is %zu.\n",
sizeof(struct ThePimp),
sizeof pimpinstance,
sizeof pimpinstance.rings,
sizeof pimpinstance.rings / sizeof *pimpinstance.rings,
sizeof pimpinstance.blings,
sizeof pimpinstance.blings / sizeof *pimpinstance.blings,
offsetof(struct ThePimp, rings),
offsetof(struct ThePimp, blings));
return 0;
}


For this implementation,
The size of a struct ThePimp is 30
and the size of an instance of it is 30.
The size of the rings array member is 10,
and it has 10 elements.
The size of the blings array member is 20,
and it has 20 elements.

The offset of the rings array member is 0;
The offset of the blings array member is 10.
 
R

REH

The "easily predicted" 4 comes from a machine where sizeof(TYPE*) = 4
because it is the native size for that machine (most likely a 32-bit
machine).

So? Where is the pointer he is trying to determine the size of. I
see two arrays, neither of which would be 4 bytes in size, regardless
of the machine.

REH
 
M

ManicQin

ManicQin said:
I'm trying to get the size of a variable in a struct by his relative
postion i.e.
///
#define offsetof(s,m) (size_t)&(((s *)0)->m)

struct ThePimp{
char rings[10];
char blings[20];

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );
///
(If I have any syntax mistakes please ignore)
You can easily predict that sizeOfBling will be 4... (sizeof(int*))
Is there any way to acomplish it?

I can't think of any way to determine the size of a member of a
structure using offsetof. You might think you can determine a
member's size by subtracting its offset from the offset of the
following member, but there could be padding.

The way to determine the size of something is to use sizeof. The only
reason to use something else is to satisfy the requirements of a bad
homework assignment. In this case, you can't apply sizeof to the
member itself given just the type, but if you have an object or
expression of type "struct ThePimp" you can apply sizeof to a member
of that object or expression.

I have a more specific method in mind, but I'm not going to post it
because I don't want to do your homework for you.

--
Keith Thompson (The_Other_Keith) <[email protected]>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

I would ignore most of the comments
but I do want to reply to somethings
1) sizeof a pointer is 4 (platform specific)
2)I did not know if offsetof is language standart or vc6 so I added it
3) this is not homework!! It is a real live crapy system that
generates reciepts that I was given to support and fix up a bit... As
for today every time we need to add a parameter to our structs I need
to add his offset and sizeof to a different array (it's not even an
array it a function with switch cases!!! yack!)
I'm just trying to fix up the system . I would prefer to delete it and
start over but hey it is not my call.

I am not a c programmer but that's why I ask questions here (after i
googled them)!

I cannot rely on people not messing with my struct so i cannot know
what is after or before the requested var thanks NOOB
and by the way the alignment is dealed thanks REH

Thanks all
 
K

Keith Thompson

ManicQin said:
I would ignore most of the comments
but I do want to reply to somethings
1) sizeof a pointer is 4 (platform specific)
2)I did not know if offsetof is language standart or vc6 so I added it
3) this is not homework!! It is a real live crapy system that
generates reciepts that I was given to support and fix up a bit... As
for today every time we need to add a parameter to our structs I need
to add his offset and sizeof to a different array (it's not even an
array it a function with switch cases!!! yack!)
I'm just trying to fix up the system . I would prefer to delete it and
start over but hey it is not my call.

I am not a c programmer but that's why I ask questions here (after i
googled them)!

I cannot rely on people not messing with my struct so i cannot know
what is after or before the requested var thanks NOOB
and by the way the alignment is dealed thanks REH

Sorry, your question looked very much like a homework assignment, and
we do get a lot of students showing up with "Please do my homework for
me" questions.

I'll take your word for it that it's a real system (though I *hope*
that it doesn't really declare a structure "ThePimp" with members
"rings" and "blings").

If you're not a C programmer, I wonder why you were assigned the task
of working on C software. On the other hand, I suppose you're a C
programmer now, but you might be in over your head. But that's
between you and whoever gave you this task.

Getting back to the point, here's the code I was hesitant to post
before:

#include <stdio.h>

int main(void)
{
struct ThePimp {
char rings[10];
char blings[20];
};
const size_t blings_size = sizeof ((struct ThePimp*)0)->blings;

printf("blings_size = %lu\n", (unsigned long)blings_size);
return 0;
}

This is how you can determine the size of a member of a struct
(blings in this case) given only the struct type, not an object
of the type. It looks ugly, but I'm reasonably sure it's safe
and portable.

"(struct ThePimp*)0" yields a null pointer of type "pointer to struct
ThePimp". A null pointer is a unique and valid pointer value that
you can't legally dereference, since it doesn't point to anything.

"((struct ThePimp*)0)->blings" dereferences the pointer and yields
the value of the "blings" member of the object that it points to.
(Yes, I know, I just said that you can't dererence it and that it
doesn't point to anything; bear with me.)

"sizeof ((struct ThePimp*)0)->blings" yields the size of the "blings"
member of this nonexistent structure. This actually works because
the "sizeof" operator doesn't evaluate its operand; all it does
is determine its operand's type and give you its size in bytes.
(There's an exception for VLAs (variable-length arrays), but that
doesn't apply here.) We needed an expression of the type of the
"blings" member, but since we only wanted to apply "sizeof" to it,
we didn't need an expression that can actually be evaluated.

(size_t is the unsigned integer type of the result of the sizeof
operator. I converted it to unsigned long so I could print it with
the "%lu" format.)

I *think* that's what you were asking for. But I would suggest
that you consider carefully whether it's really what you need.
The expression is rather obscure, and getting the size of "blings"
is going to be much easier if you have an object of type "struct
ThePimp". I would expect that, in most contexts where you need
the size of a member of a struct, you're just naturally going
to have an object of the struct type lying around, so you just
do the much simpler "sizeof struct_object.blings", or perhaps
"sizeof pointer_object->blings".

But if I really needed to use this, I'd wrap it in a macro (for one
thing, it lets me apply a name to the construct so it's easier to tell
at a glance what it's intended to do). Here's a revised version of
the program:

#include <stdio.h>

#define MEMBER_SIZE(s, m) (sizeof ((s*)0)->m)

int main(void)
{
struct ThePimp {
char rings[10];
char blings[20];
};

printf("blings size = %lu\n",
(unsigned long)MEMBER_SIZE(struct ThePimp, blings));
return 0;
}

The best advice I can give you is to read the comp.lang.c FAQ,
<http://www.c-faq.com/>. I also recommend picking up a copy of K&R2
(Kernighan & Ritchie, "The C Programming Language", 2nd edition).
 
R

REH

I would ignore most of the comments
but I do want to reply to somethings
1) sizeof a pointer is 4 (platform specific)

But you are not getting the size of a pointer, both of your fields are
arrays. The size of "rings" is 10. The size of "blings" is 20. This
will always be true, regardless of the target system, unless you
change the type of your array elements, or the number of elements in
your array.

REH
 
R

REH

I cannot rely on people not messing with my struct so i cannot know
what is after or before the requested var thanks NOOB
and by the way the alignment is dealed thanks REH


How is the alignment problem dealt with? If there is padding before a
field, it will get included in your total when your calculate
offsetof. How do you remove it?

REH
 
M

ManicQin

But you are not getting the size of a pointer, both of your fields are
arrays. The size of "rings" is 10. The size of "blings" is 20. This
will always be true, regardless of the target system, unless you
change the type of your array elements, or the number of elements in
your array.

REH
REH:
Sorry I rechecked it... The way I use it, it returns 4 (or
size_of(pointer) for the pedants)
(See the code I posted and try him - read this post all through to see
why I coded it that way)
As for the alignment: we pad our structs with "Fillers" array of chars
that complete a series of arrays to 32,
Each filler is responsible for a segment that is a devision of 32 and
for each var add the his segment the filler is updated manually...

Ha Ha Ha Keith:
In normal systems you were right... But in this hideous system I only
know the offset of the variable...
(That's why I added the offsetof in my code above...)
Are you starting to catch my drift...

There's a huge switch case goes like:
switch (param)
{
case offsetof(rings) ... return 10
case offsetof(blings)... return 20
};

p.s. I'm a c++ programmer, And I know that some people would start
arguing with me that I should know things like that because after all c
++ is a descendant of c but I can tell you that:
1)It depends on the system you are developing.
2) A well designed OO program wont need to do such a thing...

Thanks
 
B

Ben Bacarisse

ManicQin said:
REH:
Sorry I rechecked it... The way I use it, it returns 4 (or
size_of(pointer) for the pedants)
(See the code I posted and try him - read this post all through to see
why I coded it that way)

Check what REH is saying. He (or she) is saying that you seem to be
trying to get the size of something that is not a pointer. Of course
you get 4 (on your system) if you apply sizeof to a pointer, but your
code:

struct ThePimp{
char rings[10];
char blings[20];

};

int sizeOfBling = sizeof( (*char)&ThePimp +
(char)offsetof(ThePimp,blings) );

suggested you wanted the size of the part of struct (just from the
name of the variable). I think all REH is saying is that you should
not take the size of a pointer if you want the size of something else.
Ha Ha Ha Keith:
In normal systems you were right... But in this hideous system I only
know the offset of the variable...
(That's why I added the offsetof in my code above...)
Are you starting to catch my drift...

Nope. I, for one, am now lost about what your question is. Keith
Thompson told you how to get the size of struct member (which is what
I though was the question) but it seems it is not. You know how to
find the offset of a member (though you should not need to define your
own offsetof macro) so that can't be it.

Are you maybe confused as to why sizeOfBling is 4? It is 4 simply
because the type of the expression sizeof is applied to is a pointer.
Are you confused as to why adding a char to a char * gives a pointer?
There's a huge switch case goes like:
switch (param)
{
case offsetof(rings) ... return 10
case offsetof(blings)... return 20
};

That does not help us follow your problem. Are you trying to write
something like this? Are you trying to modify it in some way?
 
M

ManicQin

Ok Please dont ask me why am I writing this code the way it is, It's
an abbreviation of a much bigger complexed system
and I cant explain why it was chosen to work this way. I'm trying to
fix a particular point in the system.

I'm trying to achieve the line with the comment (and the
returnSizeofParam function) in a smaller, nicer and more DYNAMIC way.
As you can see whenever I add a new Parameter to Parameters struct I
need to update returnSizeofParamByOffest ... for me it looks a bit
crooked...
Is there a way to know the sizeof a variable in a struct only by his
offset. is it possible?

struct Parameters
{
char strIDNum[10];
char strFirstName[20];
char strFamilyName[30];
};

int returnSizeofParamByOffest(int lParamOffset)
{
Parameters cTemp;

switch (lParamOffset) {
case offsetof(Parameters,strIDNum): return sizeof(cTemp.strIDNum);
break;
case offsetof(Parameters,strFirstName): return
sizeof(cTemp.strFirstName); break;
case offsetof(Parameters,strFamilyName): return
sizeof(cTemp.strFamilyName); break;
};

return 0;
}

int main() {
Parameters cTemp= {"AAA" , "BBB" , "CCC"};
char strTempForPrinting[100] = {0};
int lParamToPrint = offsetof(Parameters , strFirstName);
int sizeOfParam =
returnSizeofParamByOffest(lParamToPrint ); //
********************

memcpy(strTempForPrinting,(char*)&cTemp + (char)lParamToPrint ,
sizeOfParam );
printf("The parameter is: %s \n",strTempForPrinting);
return 0;
}

p.s. Please tell me why I wasn't understood in the above posts. (It's
important for me to understand why there was a mis-connection)
 
B

Ben Bacarisse

Ok Please dont ask me why am I writing this code the way it is,

OK.

Is there a way to know the sizeof a variable in a struct only by his
offset. is it possible?
No.

struct Parameters
{
char strIDNum[10];
char strFirstName[20];
char strFamilyName[30];
};

int returnSizeofParamByOffest(int lParamOffset)
{
Parameters cTemp;

switch (lParamOffset) {
case offsetof(Parameters,strIDNum): return sizeof(cTemp.strIDNum);
break;
case offsetof(Parameters,strFirstName): return
sizeof(cTemp.strFirstName); break;
case offsetof(Parameters,strFamilyName): return
sizeof(cTemp.strFamilyName); break;
};

return 0;
}

int main() {
Parameters cTemp= {"AAA" , "BBB" , "CCC"};
char strTempForPrinting[100] = {0};
int lParamToPrint = offsetof(Parameters , strFirstName);
int sizeOfParam =
returnSizeofParamByOffest(lParamToPrint ); //
********************

memcpy(strTempForPrinting,(char*)&cTemp + (char)lParamToPrint ,
sizeOfParam );
printf("The parameter is: %s \n",strTempForPrinting);
return 0;
}

This is not C (I am sure you know that -- the compiler will have told
you so) but since your objective is impossible, there is no point in
trying to make it C.
p.s. Please tell me why I wasn't understood in the above posts. (It's
important for me to understand why there was a mis-connection)

I think this because you question was not clear. You may have hinted
at the above question before, but since the answer is such a clear and
obvious "no" (can you tell how many pages are in a book just from its
position on the shelf?) people may have tried to re-interpret the
hints as some other question.
 
M

ManicQin

ManicQin said:
Ok Please dont ask me why am I writing this code the way it is,

OK.

Is there a way to know the sizeof a variable in a struct only by his
offset. is it possible?
No.



struct Parameters
{
char strIDNum[10];
char strFirstName[20];
char strFamilyName[30];
};
int returnSizeofParamByOffest(int lParamOffset)
{
Parameters cTemp;
switch (lParamOffset) {
case offsetof(Parameters,strIDNum): return sizeof(cTemp.strIDNum);
break;
case offsetof(Parameters,strFirstName): return
sizeof(cTemp.strFirstName); break;
case offsetof(Parameters,strFamilyName): return
sizeof(cTemp.strFamilyName); break;
};
return 0;
}
int main() {
Parameters cTemp= {"AAA" , "BBB" , "CCC"};
char strTempForPrinting[100] = {0};
int lParamToPrint = offsetof(Parameters , strFirstName);
int sizeOfParam =
returnSizeofParamByOffest(lParamToPrint ); //
********************
memcpy(strTempForPrinting,(char*)&cTemp + (char)lParamToPrint ,
sizeOfParam );
printf("The parameter is: %s \n",strTempForPrinting);
return 0;
}

This is not C (I am sure you know that -- the compiler will have told
you so) but since your objective is impossible, there is no point in
trying to make it C.
p.s. Please tell me why I wasn't understood in the above posts. (It's
important for me to understand why there was a mis-connection)

I think this because you question was not clear. You may have hinted
at the above question before, but since the answer is such a clear and
obvious "no" (can you tell how many pages are in a book just from its
position on the shelf?) people may have tried to re-interpret the
hints as some other question.

"I'm trying to get the size of a variable in a struct by his relative
postion"
.... I thought that would be self explanatory - Never mind that now.
Thanks you just shattered my dreams of creating a better world... ;)
BTW why isnt it C?
 
R

Richard Heathfield

ManicQin said:

"I'm trying to get the size of a variable in a struct by his relative
postion"
... I thought that would be self explanatory

It is. So is "this can't be done".

Think about it. If it were possible to do that, then we could control the
size of an object simply by placing it at a certain position in the
struct. If, say, the relative position "first" yields "2 bytes", then we
could fit a double into two bytes just by making it the first member of a
structure! That simply isn't how the world works. Sorry.
 
B

Ben Bacarisse

ManicQin said:
ManicQin said:
Ok Please dont ask me why am I writing this code the way it is,

OK.

Is there a way to know the sizeof a variable in a struct only by his
offset. is it possible?
No.



struct Parameters
{
char strIDNum[10];
char strFirstName[20];
char strFamilyName[30];
};
int returnSizeofParamByOffest(int lParamOffset)
{
Parameters cTemp;
switch (lParamOffset) {
case offsetof(Parameters,strIDNum): return sizeof(cTemp.strIDNum);
break;
case offsetof(Parameters,strFirstName): return
sizeof(cTemp.strFirstName); break;
case offsetof(Parameters,strFamilyName): return
sizeof(cTemp.strFamilyName); break;
};
return 0;
}
int main() {
Parameters cTemp= {"AAA" , "BBB" , "CCC"};
char strTempForPrinting[100] = {0};
int lParamToPrint = offsetof(Parameters , strFirstName);
int sizeOfParam =
returnSizeofParamByOffest(lParamToPrint ); //
********************
memcpy(strTempForPrinting,(char*)&cTemp + (char)lParamToPrint ,
sizeOfParam );
printf("The parameter is: %s \n",strTempForPrinting);
return 0;
}

This is not C (I am sure you know that -- the compiler will have told
you so) but since your objective is impossible, there is no point in
trying to make it C.
p.s. Please tell me why I wasn't understood in the above posts. (It's
important for me to understand why there was a mis-connection)

I think this because you question was not clear. You may have hinted
at the above question before, but since the answer is such a clear and
obvious "no" (can you tell how many pages are in a book just from its
position on the shelf?) people may have tried to re-interpret the
hints as some other question.

Best not to quote sigs.
"I'm trying to get the size of a variable in a struct by his relative
postion"
... I thought that would be self explanatory - Never mind that now.

Well it was and I answered it. However, this:
BTW why isnt it C?

made me look in detail more. First the answer: it is not C because it
has syntax errors and does not comply with C's other rules. In
particular, offsetof does produce a constant suitable for use in a
switch statement. However, any switch can be replaced by if-then-else
so that would work.

Programmers look for general solutions, so your general question got
answered (at least by me) in the most general way: can't be done. The
solution for one structure, written out by hand, is so obvious that I
did not think you were asking for it:

struct S temp;
if (arg == offsetof(struct S, member1))
return sizeof temp.member1;
if (arg == offsetof(struct S, member2))
return sizeof temp.member2;

and so on. I am sorry if this sounds rude -- I really did not think
you could be asking for this. If you want something more automatic
and general, then the original answer still stands: you can't.

You can use C99 features to make it less of a maintenance problem:

-------------------
#include <stddef.h>

struct S {
int member1;
int member2;
};

size_t get_size(size_t arg)
{
struct S temp;
size_t sizes[] = {
[offsetof(struct S, member1)] = sizeof temp.member1,
[offsetof(struct S, member2)] = sizeof temp.member2,
};
return sizes[arg];
}
 
M

ManicQin

Lets say that the answer did not shock me, I thought maybe there's
something I missed so it was worth asking.
Thank You all.
 
P

pete

ManicQin wrote:
"I'm trying to get the size of a variable in a struct by his relative
postion"
... I thought that would be self explanatory

It's bizarre.
It's like "I'm trying to shoot a target by stabbing at it with a knife."

You use the sizeof operator to get the size of a variable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top