tricky casting question with anonymous structs
Author |
Message |
Andreas Leitne #1 / 21
|
tricky casting question with anonymous structs
Hi, I need to write a c expression in ANSI C. I can only write this one C expression, because the expression has to go into some external clause of a non C language. (Complicated, but doesn't add to the problem. Fact being I can only write an expression, no statements) Now what I have is an anonymous struct with an alias: typedef struct { int a; Quote: } **ppfoo;
Now, i need to access 'a' given a void* p, which i know is just a pointer to above struct. I think this will do the trick: (*(ppfoo)&p)->a Now, the problem I cannot solve anymore is when the alias has a triple indirection as in: typedef struct { int a; Quote: } ***pppfoo;
(**(ppfoo)&&p)->a does not work, because i cannot do the &&. The struct is a given, I do not have influence on it and I cannot write arbitrary statements, I can only write one expression. So what I have is: I have a anonymous struct, which has an alias with a triple indirection. Now I have a void* which i need to cast to be a pointer to the struct (single indirection), but there is no alias for that type - and I don't seem to know a workaround. Does anybody have a solution for that? Any help will be greatly appreciated. regards, Andreas
|
Fri, 24 Jun 2005 03:24:18 GMT |
|
|
rjh #2 / 21
|
tricky casting question with anonymous structs
[Could someone scrutinise this reply carefully please? Thanks.] Quote:
> Hi, > I need to write a c expression in ANSI C. I can only write this one C > expression, because the expression has to go into some external clause of > a non C language. (Complicated, but doesn't add to the problem. Fact being > I can only write an expression, no statements) > Now what I have is an anonymous struct with an alias: > typedef struct > { > int a; > } **ppfoo; > Now, i need to access 'a' given a void* p, which i know is just a pointer > to above struct. I think this will do the trick: > (*(ppfoo)&p)->a
No. Build up logically: struct foo_ { int a; Quote: };
typedef struct foo_ foo; typedef foo *pfoo; typedef pfoo *ppfoo; typedef ppfoo *pppfoo; foo Instance = {42}; pfoo p1 = &Instance; ppfoo p2 = &p1; pppfoo p3 = &p2; void *vp = p1; printf("%d\n", ((pfoo)vp)->a); vp = p2; printf("%d\n", (*(ppfoo)vp)->a); vp = p3; printf("%d\n", (**(pppfoo)vp)->a); Not compiled or tested, I'm afraid. --
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Fri, 24 Jun 2005 03:39:04 GMT |
|
|
Mathew Hendr #3 / 21
|
tricky casting question with anonymous structs
On Sun, 05 Jan 2003 19:24:18 GMT, "Andreas Leitner" Quote:
>I need to write a c expression in ANSI C. I can only write this one C >expression, because the expression has to go into some external clause of >a non C language. (Complicated, but doesn't add to the problem. Fact being >I can only write an expression, no statements) >Now what I have is an anonymous struct with an alias: >typedef struct >{ > int a; >} **ppfoo; >Now, i need to access 'a' given a void* p, which i know is just a pointer >to above struct. I think this will do the trick: > (*(ppfoo)&p)->a
Even that is not strictly legal. Quote: >Now, the problem I cannot solve anymore is when the alias has a triple >indirection as in: >typedef struct >{ > int a; >} ***pppfoo; >(**(ppfoo)&&p)->a >does not work, because i cannot do the &&. The struct is a given, I do >not have influence on it and I cannot write arbitrary statements, I can >only write one expression.
I don't think a standard C solution is possible. But depending on your compiler perhaps you can use typeof, which is supported by gcc at least. -- Mat.
|
Fri, 24 Jun 2005 03:50:47 GMT |
|
|
Andreas Leitne #4 / 21
|
tricky casting question with anonymous structs
Hi rjh, thanks for your quick reply. Quote:
> [Could someone scrutinise this reply carefully please? Thanks.]
>> Hi, >> I need to write a c expression in ANSI C. I can only write this one C >> expression, because the expression has to go into some external clause of >> a non C language. (Complicated, but doesn't add to the problem. Fact being >> I can only write an expression, no statements) >> Now what I have is an anonymous struct with an alias: >> typedef struct >> { >> int a; >> } **ppfoo; >> Now, i need to access 'a' given a void* p, which i know is just a pointer >> to above struct. I think this will do the trick: >> (*(ppfoo)&p)->a > No. Build up logically:
Ooops, I forgot to mention, I cannot change the struct (it's a weird situation I am writing a generator for something and I need to accept arbitrary C code). Btw, I found out, I cannot even handle a much simpler case: typedef struct { int a;} *pfoo; how can i, in an expression, determine the size of the struct (not the pointer to the struct). sizeof (pfoo) will always give me the size of the pointer to the struct, not what i want pfoo dummy; sizeof (dummy*) needs an extra statement, cannot do that. regards, Andreas
|
Fri, 24 Jun 2005 03:52:57 GMT |
|
|
Ben Pfaf #5 / 21
|
tricky casting question with anonymous structs
Quote:
> typedef struct > { int a;} *pfoo; > how can i, in an expression, determine the size of the struct (not the > pointer to the struct).
sizeof *pfoo -- "It would be a much better example of undefined behavior if the behavior were undefined." --Michael Rubenstein
|
Fri, 24 Jun 2005 03:54:37 GMT |
|
|
rjh #6 / 21
|
tricky casting question with anonymous structs
Quote:
> Hi rjh, > thanks for your quick reply.
>> [Could someone scrutinise this reply carefully please? Thanks.]
>>> Hi, >>> I need to write a c expression in ANSI C. I can only write this one C >>> expression, because the expression has to go into some external clause >>> of a non C language. (Complicated, but doesn't add to the problem. Fact >>> being I can only write an expression, no statements) >>> Now what I have is an anonymous struct with an alias: >>> typedef struct >>> { >>> int a; >>> } **ppfoo; >>> Now, i need to access 'a' given a void* p, which i know is just a >>> pointer to above struct. I think this will do the trick: >>> (*(ppfoo)&p)->a >> No. Build up logically: > Ooops, I forgot to mention, I cannot change the struct (it's a weird > situation I am writing a generator for something and I need to accept > arbitrary C code).
You don't have to. My earlier reply was designed to show how to build up the cast expression from first principles. Read it again, and I think you'll be okay. Quote: > Btw, I found out, I cannot even handle a much simpler case: > typedef struct > { int a;} *pfoo; > how can i, in an expression, determine the size of the struct (not the > pointer to the struct).
sizeof *p If p is void *, then sizeof *(whatever *)p will do instead. --
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Fri, 24 Jun 2005 04:12:24 GMT |
|
|
Andreas Leitne #7 / 21
|
tricky casting question with anonymous structs
Hi Ben, thanks for you reply! Quote:
>> typedef struct >> { int a;} *pfoo; >> how can i, in an expression, determine the size of the struct (not the >> pointer to the struct). > sizeof *pfoo
That's not valid ANSI C, is it? At least gcc tells me that (parse error before 'pfoo') regards, Andreas
|
Fri, 24 Jun 2005 04:20:41 GMT |
|
|
Andreas Leitne #8 / 21
|
tricky casting question with anonymous structs
Hi rjh, again thanks alot for your reply. Quote:
>> Ooops, I forgot to mention, I cannot change the struct (it's a weird >> situation I am writing a generator for something and I need to accept >> arbitrary C code). > You don't have to. My earlier reply was designed to show how to build up the > cast expression from first principles. Read it again, and I think you'll be > okay.
Well, see my void* p is a pointer to the anonymous struct, in your code you assume it is a pointer to a pointer (etc.) to a struct. Here is an example of your code: vp = p3; printf("%d\n", (**(pppfoo)vp)->a); That of course would work, only in my case what I have is: vp = p1; printf("%d\n", (**(pppfoo)vp)->a); And this of course cannot work, because the cast of 'vp' from 'void*' to 'pppfoo' is invalid and will return a segfault at best. Quote: >> Btw, I found out, I cannot even handle a much simpler case: >> typedef struct >> { int a;} *pfoo; >> how can i, in an expression, determine the size of the struct (not the >> pointer to the struct). > sizeof *p > If p is void *, then sizeof *(whatever *)p will do instead.
What is p? I don't have any? I know I have a lot of constraints, but I need to formulate everything in an expression. And for the size, the constraints are the following: * I know an alias of the struct, * the struct itself is anonymous, * i know the number of indirections between the alias and the anonymous struct * i need to write an expression which when evaluated returns the size of the anonymous struct. regards, Andreas
|
Fri, 24 Jun 2005 04:29:42 GMT |
|
|
Ben Pfaf #9 / 21
|
tricky casting question with anonymous structs
Quote:
> Hi Ben, > thanks for you reply!
> >> typedef struct > >> { int a;} *pfoo; > >> how can i, in an expression, determine the size of the struct (not the > >> pointer to the struct). > > sizeof *pfoo > That's not valid ANSI C, is it? At least gcc tells me that (parse error > before 'pfoo')
Oops, sorry, I missed the `typedef' keyword. -- "A lesson for us all: Even in trivia there are traps." --Eric Sosman
|
Fri, 24 Jun 2005 04:31:27 GMT |
|
|
rjh #10 / 21
|
tricky casting question with anonymous structs
Quote:
> Hi rjh, > again thanks alot for your reply.
No problem, although this is getting to be a bit confusing. :-) <snip> Quote: > vp = p3; > printf("%d\n", (**(pppfoo)vp)->a); > That of course would work, only in my case what I have is: > vp = p1; > printf("%d\n", (**(pppfoo)vp)->a); > And this of course cannot work, because the cast of 'vp' from 'void*' to > 'pppfoo' is invalid and will return a segfault at best.
If your void pointer is pointing directly at the struct, then you just do printf("%d\n", ((pfoo)vp)->a); Quote: >> If p is void *, then sizeof *(whatever *)p will do instead. > What is p? I don't have any?
I was given to understand that you had a pointer to some struct, which was given to you as a void *. Now, if you don't know (at compile time) what type the struct is (e.g. if it could be one of a number of structs and you have no way to disambiguate them), then you have too many constraints - and you're stuck. Quote: > I know I have a lot of constraints, but I > need to formulate everything in an expression. And for the size, the > constraints are the following: > * I know an alias of the struct, > * the struct itself is anonymous, > * i know the number of indirections between the alias and the anonymous > struct > * i need to write an expression which when evaluated returns the size of > the anonymous struct.
Consider this code: #include <stdio.h> #include <time.h> #include <stdlib.h> void printsize(void *p); int main(void) { struct tm tmt; div_t dt; printsize(&tmt); printsize(&dt); return 0; Quote: }
If this accurately summarises your problem, then printsize() is, I believe, impossible to write in ISO C, given the constraints under which you are working. Sorry, but them's the breaks. (I hope I'm wrong, for your sake. Perhaps someone else will come up with something.) --
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Fri, 24 Jun 2005 06:35:34 GMT |
|
|
Andreas Leitne #11 / 21
|
tricky casting question with anonymous structs
Quote:
>> Hi rjh, >> again thanks alot for your reply. > No problem, although this is getting to be a bit confusing. :-)
Again thanks. Ok let me give you some background. I am writting a tool that reads in C header files and generate Eiffel code that wraps the C code. So for example, you want to write an app in Eiffel that uses gtk2 as GUI. There currently is no binding. Writing bindings is tedious, my tool tries to take the tedious part out of that by makeing for example for every struct foo a class FOO that has features to get and set the structs members based on a pointer to that struct. In Eiffel there are no pointers, only references. To keep things simple on the Eiffel side, I would like model all structs as references too. So using C++ pseudo code i would get for: typedef struct { int a; Quote: } ***pppfoo;
class FOO { public FOO () { } public int get_size () { ... } public int get_a (void * p) {...} public void set_a (void * p, int a) {...} Quote: };
In reality this class is of course written in Eiffel. And all the restrictions come from that the c subset I can use in Eiffel is limited (i can write c code where the ... are). Whatever you do, 'p' must always be a pointer to the struct. I hope that clarifies my dilemma a little. Quote: > <snip> >> vp = p3; >> printf("%d\n", (**(pppfoo)vp)->a); >> That of course would work, only in my case what I have is: >> vp = p1; >> printf("%d\n", (**(pppfoo)vp)->a); >> And this of course cannot work, because the cast of 'vp' from 'void*' to >> 'pppfoo' is invalid and will return a segfault at best. > If your void pointer is pointing directly at the struct, then you just do > printf("%d\n", ((pfoo)vp)->a); >>> If p is void *, then sizeof *(whatever *)p will do instead. >> What is p? I don't have any? > I was given to understand that you had a pointer to some struct, which was > given to you as a void *. Now, if you don't know (at compile time) what > type the struct is (e.g. if it could be one of a number of structs and you > have no way to disambiguate them), then you have too many constraints - and > you're stuck.
I don't know the name of the struct (because it is anonymous), but an alias (which also has indirections). But there is no ambiguity. Quote: > Consider this code: > #include <stdio.h> > #include <time.h> > #include <stdlib.h> > void printsize(void *p); > int main(void) > { > struct tm tmt; > div_t dt; > printsize(&tmt); > printsize(&dt); > return 0; > } > If this accurately summarises your problem, then printsize() is, I believe, > impossible to write in ISO C, given the constraints under which you are > working. Sorry, but them's the breaks. (I hope I'm wrong, for your sake. > Perhaps someone else will come up with something.)
No, one function always only deals with one kind of struct. It's only the cast to a type who has no name is problematic for me (; regards, Andreas
|
Fri, 24 Jun 2005 07:34:09 GMT |
|
|
Arthur J. O'Dwye #12 / 21
|
tricky casting question with anonymous structs
Quote:
<snipped> > In Eiffel there are no pointers, only references. To keep things simple on > the Eiffel side, I would like model all structs as references too. So > using C++ pseudo code i would get for: > typedef struct > { > int a; > } ***pppfoo;
So to allocate an actual "foo" with value "SOMETHING", you'd have to write it as follows, correct?: pppfoo p = malloc(sizeof *p); *p = malloc(sizeof **p); **p = malloc(sizeof ***p); (**p)->a = SOMETHING; Quote: > class FOO > { > public FOO () > { > } > public int get_size () { ... } > public int get_a (void * p) {...} > public void set_a (void * p, int a) {...} > }; > In reality this class is of course written in Eiffel.
Okay, I'm confused now. I understand that you're trying to mix Eiffel, C, and C++ in a sort of polyglot here, but I don't see which parts are supposed to be which. A little bit of real code might help... Quote: > And all the restrictions come from that the c subset > I can use in Eiffel is limited (i can write c code where the ... are). > Whatever you do, 'p' must always be a pointer to the struct.
A pointer (one level of indirection), or a pppfoo (three levels of indirection)? Quote: > I hope that clarifies my dilemma a little. > > <snip> > >> vp = p3; > >> printf("%d\n", (**(pppfoo)vp)->a); > >> That of course would work, only in my case what I have is: > >> vp = p1; > >> printf("%d\n", (**(pppfoo)vp)->a); > >> And this of course cannot work, because the cast of 'vp' from 'void*' to > >> 'pppfoo' is invalid and will return a segfault at best.
Right. Richard gave you this solution: typedef struct { int a; } ***pppfoo; pppfoo appp; void *vp = appp; printf("%d\n", (***(pppfoo)vp).a ); But you really need this solution: typedef struct { int a; } ***pppfoo; pppfoo appp; void *vp = **appp; printf("%d\n", (*(pfoo)vp).a ); except that typedef "pfoo" hasn't been given to you. I'm thinking, I'm thinking... but I think I may be stuck here. Standard C may not have any answers for you. Quote: > regards, > Andreas
Good luck! -Arthur
|
Fri, 24 Jun 2005 08:31:53 GMT |
|
|
Kevin Easto #13 / 21
|
tricky casting question with anonymous structs
Quote:
>> Hi rjh, >> again thanks alot for your reply. > No problem, although this is getting to be a bit confusing. :-) > <snip> >> vp = p3; >> printf("%d\n", (**(pppfoo)vp)->a); >> That of course would work, only in my case what I have is: >> vp = p1; >> printf("%d\n", (**(pppfoo)vp)->a); >> And this of course cannot work, because the cast of 'vp' from 'void*' to >> 'pppfoo' is invalid and will return a segfault at best. > If your void pointer is pointing directly at the struct, then you just do > printf("%d\n", ((pfoo)vp)->a);
The problem he has is that this is the line he needs, but he only has the ``ppfoo'' type available. I don't think there is a solution in standard C. I think the typeof extension can be used: ((typeof *(ppfoo)vp)vp)->a But all I know of typeof is what was posted in the concurrent thread crossposted with comp.std.c talking about standardising extensions like these. - Kevin.
|
Fri, 24 Jun 2005 10:12:29 GMT |
|
|
Kevin Easto #14 / 21
|
tricky casting question with anonymous structs
Quote:
> Hi rjh, > again thanks alot for your reply.
>>> Btw, I found out, I cannot even handle a much simpler case: >>> typedef struct >>> { int a;} *pfoo; >>> how can i, in an expression, determine the size of the struct (not the >>> pointer to the struct). >> sizeof *p >> If p is void *, then sizeof *(whatever *)p will do instead. > What is p? I don't have any? I know I have a lot of constraints, but I > need to formulate everything in an expression. And for the size, the > constraints are the following: > * I know an alias of the struct, > * the struct itself is anonymous, > * i know the number of indirections between the alias and the anonymous > struct > * i need to write an expression which when evaluated returns the size of > the anonymous struct.
sizeof *(pfoo)0 I _think_ this is OK, because it is specified that sizeof does not evaluate it's argument. Even if it's technically not OK, it's your only choice. - Kevin.
|
Fri, 24 Jun 2005 10:15:33 GMT |
|
|
CBFalcone #15 / 21
|
tricky casting question with anonymous structs
Quote:
... snip ... > >> Btw, I found out, I cannot even handle a much simpler case: > >> typedef struct > >> { int a;} *pfoo; > >> how can i, in an expression, determine the size of the struct > >> (not the pointer to the struct). > > sizeof *p > > If p is void *, then sizeof *(whatever *)p will do instead. > What is p? I don't have any? I know I have a lot of constraints, > but I need to formulate everything in an expression. And for the > size, the constraints are the following:
What about: pfoo foop; size_t sz; ... foop = malloc(sizeof *foop); sz = sizeof *foop; --
Available for consulting/temporary embedded and systems. <http://cbfalconer.home.att.net> USE worldnet address!
|
Fri, 24 Jun 2005 12:35:19 GMT |
|
|
Page 1 of 2
|
[ 21 post ] |
|
Go to page:
[1]
[2] |
|