Thread overview
Overloading struct members (or cast?)
Nov 18, 2014
Wsdes
Nov 18, 2014
bearophile
Nov 18, 2014
Ali Çehreli
Nov 19, 2014
Ali Çehreli
November 18, 2014
Hello again and welcome to another tale of mystery :)

I, again, am facing problems connecting my D program to the C API as seen in the callback thread before.

I want to write a callback function that is assigned to a struct member. The function should write data from members of another struct to the command line. Please consider my code:


   void MyCB(void* pVoid) {
     DataInfo_t* userData; //DataInfo_t is a struct
     userData = cast(DataInfo_t*) pVoid;

     writeln("Value: ", pMsgUserData.Values[i].value.string);
   }

Here the DataInfo_t struct has a member Values which itself is a struct. The programmer of the API called the members of the union inside the Values struct after simple data types or pointers to them, specifically

     union value {
          const char       *string;
     }

When I try to compile I get the following error:

           Error: need 'this' for 'string' of type 'const(char*)'

I'm not quite sure what the error wants to tell me. The way I see it is that there is some kind of problem with the instance of the struct and hence the reference to that specific member value does not work.

Any ideas?

November 18, 2014
Wsdes:

union value {
>           const char       *string;
>      }

Try:

union Value {
    const char* myString;
}

Note the upper caseing, the spacing after the star, and the "string" name replaced with something else.

Bye,
bearophile
November 18, 2014
On 11/18/2014 07:32 AM, Wsdes wrote:

>             Error: need 'this' for 'string' of type 'const(char*)'

Reduced:

struct S
{
    union Value
    {
        const char* myString;
    }
}

void main()
{
    auto s = S();
    auto mine = s.Value.myString;    // ERROR
}

You may be thinking that Value introduces a name scope so that you can reference its myString by Value.myString.

You have two options:


a) Remove Value so that it is an anonymous union. myString becomes a direct member of S:

struct S
{
    union    // <-- Anonymous
    {
        const char* myString;
    }
}

void main()
{
    auto s = S();
    auto mine = s.myString;    // <-- No more Value
}


b) Make S have an actual member of type Value:

struct S
{
    union Value
    {
        const char* myString;
    }

    Value value;    // <-- Added
}

void main()
{
    auto s = S();
    auto mine = s.value.myString;    // <-- Note lower initial
}

Ali

November 18, 2014
On 11/18/14 1:28 PM, Ali Çehreli wrote:
> On 11/18/2014 07:32 AM, Wsdes wrote:
>
>  >             Error: need 'this' for 'string' of type 'const(char*)'
>
> Reduced:
>
> struct S
> {
>      union Value
>      {
>          const char* myString;
>      }
> }
>
> void main()
> {
>      auto s = S();
>      auto mine = s.Value.myString;    // ERROR
> }
>
> You may be thinking that Value introduces a name scope so that you can
> reference its myString by Value.myString.
>
> You have two options:
>
>
> a) Remove Value so that it is an anonymous union. myString becomes a
> direct member of S:
>
> struct S
> {
>      union    // <-- Anonymous
>      {
>          const char* myString;
>      }
> }
>
> void main()
> {
>      auto s = S();
>      auto mine = s.myString;    // <-- No more Value
> }
>
>
> b) Make S have an actual member of type Value:
>
> struct S
> {
>      union Value
>      {
>          const char* myString;
>      }
>
>      Value value;    // <-- Added
> }
>
> void main()
> {
>      auto s = S();
>      auto mine = s.value.myString;    // <-- Note lower initial
> }
>
> Ali
>

This works in C++:

struct S
{
   union
   {
      const char *myString;
   } Value;
};

But the issue is that D does not require the semicolon at the end of the struct, so by the closing brace, it is done with the union.

the closest solution you can get is the last one you said.

I never even considered that you can't make an anonymous struct or union type and assign it to a member in D. Not sure if we really need to support it though.

-Steve


November 19, 2014
On 11/18/2014 11:01 AM, Steven Schveighoffer wrote:

> This works in C++:
>
> struct S
> {
>     union
>     {
>        const char *myString;
>     } Value;
> };
>
> But the issue is that D does not require the semicolon at the end of the
> struct, so by the closing brace, it is done with the union.

Interesting. It never occurred to me that the lack of semicolons could have that effect.

> the closest solution you can get is the last one you said.
>
> I never even considered that you can't make an anonymous struct or union
> type and assign it to a member in D. Not sure if we really need to
> support it though.

I wouldn't miss that feature. :)

If I am not mistaken, the only "benefit" of anonymous types is that they cannot refer to themselves. I remember reading in a C++ thread years ago that anonymous types could not have contructors, destructors, and assignment operators either because they could not spell out the name of the type to define such functions.

Ali