tricky casting question with anonymous structs 
Author Message
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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.

- Show quoted text -

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  
 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  
 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  
 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  
 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  
 
 [ 21 post ]  Go to page: [1] [2]

 Relevant Pages 

1. QUESTION: Type casting between struct A superset of struct B

2. casting of struct element void pointer casting

3. cast pointer to struct to pointer to type of first member of struct

4. anonymous struct

5. anonymous structs and unions : legal?

6. tricky stuff on struct forward references

7. What are some tricky C questions?

8. tricky string-splitting question!

9. Interview question - tricky

10. Tricky macro question

11. Bitwise & operator tricky question

12. tricky interview questions

 

 
Powered by phpBB® Forum Software