Thread overview
need 'this' to access data member
Sep 27, 2006
clayasaurus
Sep 27, 2006
clayasaurus
Sep 27, 2006
Derek Parnell
Sep 27, 2006
clayasaurus
Sep 27, 2006
Mike Parker
Sep 27, 2006
Mike Parker
September 27, 2006
Hi, I have the following code attached, and I do not understand why I can not access this data member. Help is very much appreciated, thanks.

~ Clay


September 27, 2006
clayasaurus wrote:
> Hi, I have the following code attached, and I do not understand why I can not access this data member. Help is very much appreciated, thanks.
> 
> ~ Clay
> 
> 
> ------------------------------------------------------------------------
> 
> // datafield hacks
> alias int FILE; alias int Uint8; 
> 
> // structure
> struct SDL_RWops
> {
> 
>     int (*seek)(SDL_RWops *context, int offset, int whence);
>     int (*read)(SDL_RWops *context, void *ptr, int size, int maxnum);
>     int (*write)(SDL_RWops *context, void *ptr, int size, int num);
>     int (*close)(SDL_RWops *context);
>     uint type;
> 	
>     union hide
>     {
>         version(Windows)
>         {
>             struct win32io
>             {
>                 int append;
>                 void *h;
>             }
>         }
>         struct stdio
>         {
>             int autoclose;
>             FILE *fp;
>         }
>         struct mem
>         {
>             Uint8 *base;
>             Uint8 *here;
>             Uint8 *stop;
>         }
>         struct unknown
>         {
>             void *data1;
>         }
>     }
> 	hide hidden; 	
> }
> 
> 
> int main()
> {
>     SDL_RWops w; 
> 
>     // need 'this' to access data member data1??
>     w.hidden.unknown.data1 = null; 
> 
>     return 0; }

Because 'SDL_RWops.hidden.unknown' is a struct type decleration, not a field decleration.  In the same way that you had to create a field of type 'hide' in order to access its components ('hidden') you also need a field of type 'unknown' to do so.

-- Chris Nicholson-Sauls
September 27, 2006
Chris Nicholson-Sauls wrote:
> clayasaurus wrote:
>> Hi, I have the following code attached, and I do not understand why I can not access this data member. Help is very much appreciated, thanks.
>>
>> ~ Clay
>>
>>
>> ------------------------------------------------------------------------
>>
>> // datafield hacks
>> alias int FILE; alias int Uint8;
>> // structure
>> struct SDL_RWops
>> {
>>
>>     int (*seek)(SDL_RWops *context, int offset, int whence);
>>     int (*read)(SDL_RWops *context, void *ptr, int size, int maxnum);
>>     int (*write)(SDL_RWops *context, void *ptr, int size, int num);
>>     int (*close)(SDL_RWops *context);
>>     uint type;
>>         union hide
>>     {
>>         version(Windows)
>>         {
>>             struct win32io
>>             {
>>                 int append;
>>                 void *h;
>>             }
>>         }
>>         struct stdio
>>         {
>>             int autoclose;
>>             FILE *fp;
>>         }
>>         struct mem
>>         {
>>             Uint8 *base;
>>             Uint8 *here;
>>             Uint8 *stop;
>>         }
>>         struct unknown
>>         {
>>             void *data1;
>>         }
>>     }
>>     hide hidden;     }
>>
>>
>> int main()
>> {
>>     SDL_RWops w;
>>     // need 'this' to access data member data1??
>>     w.hidden.unknown.data1 = null;
>>     return 0; }
> 
> Because 'SDL_RWops.hidden.unknown' is a struct type decleration, not a field decleration.  In the same way that you had to create a field of type 'hide' in order to access its components ('hidden') you also need a field of type 'unknown' to do so.
> 
> -- Chris Nicholson-Sauls

Thanks.
~ Clay
September 27, 2006
On Tue, 26 Sep 2006 22:22:05 -0500, clayasaurus wrote:

> Hi, I have the following code attached, and I do not understand why I can not access this data member. Help is very much appreciated, thanks.

As explained already, a named union/struct must also have a data declaration before you can refer to its members. However, have you considered anonymous union/struct ? When you use these, you can refer to the members without having to qualify their names.

import std.stdio;
// datafield hacks
alias int FILE;
alias int Uint8;

// structure
struct SDL_RWops
{

    int (*seek)(SDL_RWops *context, int offset, int whence);
    int (*read)(SDL_RWops *context, void *ptr, int size, int maxnum);
    int (*write)(SDL_RWops *context, void *ptr, int size, int num);
    int (*close)(SDL_RWops *context);
    uint type;

    union
    {
        version(Windows)
        {
            struct
            {
                int append;
                void *h;
            }
        }
        struct
        {
            int autoclose;
            FILE *fp;
        }
        struct
        {
            Uint8 *base;
            Uint8 *here;
            Uint8 *stop;
        }
        struct
        {
            void *data1;
        }
    }
}


int main()
{
    SDL_RWops w;

    // need 'this' to access data member data1??
    std.stdio.writefln("autoclose A:" , w.autoclose);

    w.data1 = &w; // sample data
    std.stdio.writefln("autoclose B:" , w.autoclose);

    version(Windows)
    {
     w.append = 42; // sample data
     std.stdio.writefln("autoclose B:" , w.autoclose);
    }
    return 0;
}



-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
27/09/2006 3:22:49 PM
September 27, 2006
Derek Parnell wrote:
> On Tue, 26 Sep 2006 22:22:05 -0500, clayasaurus wrote:
> 
>> Hi, I have the following code attached, and I do not understand why I can not access this data member. Help is very much appreciated, thanks.
> 
> As explained already, a named union/struct must also have a data
> declaration before you can refer to its members. However, have you
> considered anonymous union/struct ? When you use these, you can refer to
> the members without having to qualify their names.
> 
> import std.stdio;
> // datafield hacks
> alias int FILE;
> alias int Uint8;
> 
> // structure
> struct SDL_RWops
> {
> 
>     int (*seek)(SDL_RWops *context, int offset, int whence);
>     int (*read)(SDL_RWops *context, void *ptr, int size, int maxnum);
>     int (*write)(SDL_RWops *context, void *ptr, int size, int num);
>     int (*close)(SDL_RWops *context);
>     uint type;
> 
>     union
>     {
>         version(Windows)
>         {
>             struct
>             {
>                 int append;
>                 void *h;
>             }
>         }
>         struct
>         {
>             int autoclose;
>             FILE *fp;
>         }
>         struct
>         {
>             Uint8 *base;
>             Uint8 *here;
>             Uint8 *stop;
>         }
>         struct
>         {
>             void *data1;
>         }
>     }
> }
> 
> 
> int main()
> {
>     SDL_RWops w;
> 
>     // need 'this' to access data member data1??
>     std.stdio.writefln("autoclose A:" , w.autoclose);
> 
>     w.data1 = &w; // sample data
>     std.stdio.writefln("autoclose B:" , w.autoclose);
> 
>     version(Windows)
>     {
>      w.append = 42; // sample data
>      std.stdio.writefln("autoclose B:" , w.autoclose);
>     }
>     return 0;
> }
> 

That would be nicer, but it is not my call. The SDL_RWops structure is from the SDL library (www.libsdl.org) and the goal is to stay as close to the original structure as possible.





September 27, 2006
clayasaurus wrote:

>>
> 
> That would be nicer, but it is not my call. The SDL_RWops structure is from the SDL library (www.libsdl.org) and the goal is to stay as close to the original structure as possible.
> 
> 

In C, named inner structs and unions are treated as fields.

This...

##############
typedef struct
{
   struct foo
   {
      int x;
   }
} MyStruct;

MyStruct ms;
ms.foo.x = 0;
##############

...is identical to this...

##############
typedef struct
{
   int x;
} Foo;

typedef struct
{
   Foo foo;
} MyStruct;

MyStruct ms;
ms.foo.x = 0;
##############

Assuming a 32 bit C compiler, both sizeof(MyStruct) in both examples above should output '4'.

In D, inner structs and unions are treated as type declarations but not members. Here is the same example in D:

##############
struct MyStruct
{
   struct foo
   {
      int x;
   }
}
MyStruct ms;
ms.foo.x = 0; // Error
#############

MyStruct.sizeof will output 1 in this example. Not only is foo not accessible as a member field, MyStruct is incompatible with the C side of the house. The following version fixes both issues:

##############
struct MyStruct
{
   struct Foo
   {
      int x;
   }
   Foo foo;
}
MyStruct ms;
ms.foo.x = 0;
##############

Now the output of MyStruct.sizeof should be the same as the C version.

DerelictSDL was a tedious port, so I'm surprised more silliness like this hasn't turned up yet. I'm glad you caught it.
September 27, 2006
Mike Parker wrote:
> clayasaurus wrote:
> 
>>>
>>
>> That would be nicer, but it is not my call. The SDL_RWops structure is from the SDL library (www.libsdl.org) and the goal is to stay as close to the original structure as possible.
>>
>>
> 
> In C, named inner structs and unions are treated as fields.
> 

And now that I've posted that I see that Derek was talking about anonymous inner structs. Oh well, what I said is still true :)