Thread overview
alias fails to compile
Apr 22, 2019
Stefan Koch
Apr 22, 2019
Alex
Apr 22, 2019
Adam D. Ruppe
Apr 22, 2019
aliak
April 22, 2019
What am I doing wrong here?

struct A
{
    union B
    {
        int bb;
    }
    B b;
    alias aa = B.bb;
}

void main()
{
    A a = A();
    // a.b.bb = 4; // works
    a.aa = 4; // fails
}


https://run.dlang.io/is/kXaVy2
April 22, 2019
On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran wrote:
> What am I doing wrong here?
>
> struct A
> {
>     union B
>     {
>         int bb;
>     }
>     B b;
>     alias aa = B.bb;
> }
>
> void main()
> {
>     A a = A();
>     // a.b.bb = 4; // works
>     a.aa = 4; // fails
> }
>
>
> https://run.dlang.io/is/kXaVy2

You are aliasing B.init.bb;
You should try aliasing b.bb;

though I am not sure in that'll work since alias is really only meant for symbols.
April 22, 2019
On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran wrote:
> What am I doing wrong here?
>
> struct A
> {
>     union B
>     {
>         int bb;
>     }
>     B b;
>     alias aa = b.bb;
> }
>
> void main()
> {
>     A a = A();
>     // a.b.bb = 4; // works
>     a.aa = 4; // fails
> }
>
>
> https://run.dlang.io/is/kXaVy2

aa is a "static" semantic.

your statement a.aa does not get translated in to a.b.bb like you think it does.

You are doing nothing any different than A.aa = 4.

which, when you realize this you'll understand the "need this" error.


It's as if you are doing

> struct A
> {
>     union B
>     {
>         int bb;
>     }
>     B b;
> }
     alias aa = A.b.bb;

aa = 4;

which is like trying to say

A.b.bb = 4;


In D we can access "static" stuff using the object and so this can make things look like the mean something they are not.

If you could magically pass the this to it using something like UFCS then it could work.

import std.stdio;
struct A
{
    union B
    {
        int bb;
    }
    B b;
    alias aa = (ref typeof(this) a) { return &a.b; };
}

void main()
{
    A a = A();
    a.b.bb = 4;
    a.aa(a).bb = 5;
    writeln(a.aa(a).bb);
}

But here a.aa is not aa(a) and UFCS does not work so one must first access the alias and then pass the this.

Basically you are not going to get it to work. Just not how the semantics works.

It would be nice if a.aa(a) could reduce to a.aa as is UFCS was smart enough to realize it could pass it to the alias as this, but it doesn't.

else one might could do

alias aa = this.b.bb;

and

a.aa = 4;




April 22, 2019
On Monday, 22 April 2019 at 14:07:11 UTC, Alex wrote:
> On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran wrote:
>> What am I doing wrong here?
>>
>> struct A
>> {
>>     union B
>>     {
>>         int bb;
>>     }
>>     B b;
>>     alias aa = b.bb;
>> }
>>
>> void main()
>> {
>>     A a = A();
>>     // a.b.bb = 4; // works
>>     a.aa = 4; // fails
>> }
>>
>>
>> https://run.dlang.io/is/kXaVy2
>
> aa is a "static" semantic.
>
> your statement a.aa does not get translated in to a.b.bb like you think it does.
>
> You are doing nothing any different than A.aa = 4.
>
> which, when you realize this you'll understand the "need this" error.
>
>
> It's as if you are doing
>
>> struct A
>> {
>>     union B
>>     {
>>         int bb;
>>     }
>>     B b;
>> }
>      alias aa = A.b.bb;
>
> aa = 4;
>
> which is like trying to say
>
> A.b.bb = 4;
>
>
> In D we can access "static" stuff using the object and so this can make things look like the mean something they are not.
>
> If you could magically pass the this to it using something like UFCS then it could work.
>
> import std.stdio;
> struct A
> {
>     union B
>     {
>         int bb;
>     }
>     B b;
>     alias aa = (ref typeof(this) a) { return &a.b; };
> }
>
> void main()
> {
>     A a = A();
>     a.b.bb = 4;
>     a.aa(a).bb = 5;
>     writeln(a.aa(a).bb);
> }
>
> But here a.aa is not aa(a) and UFCS does not work so one must first access the alias and then pass the this.
>
> Basically you are not going to get it to work. Just not how the semantics works.
>
> It would be nice if a.aa(a) could reduce to a.aa as is UFCS was smart enough to realize it could pass it to the alias as this, but it doesn't.
>
> else one might could do
>
> alias aa = this.b.bb;
>
> and
>
> a.aa = 4;

I see. This is a simplified use case in /usr/include/net/if.h on Linux, where struct ifreq has something like this:

struct ifreq
  {
# define IFHWADDRLEN    6
# define IFNAMSIZ   IF_NAMESIZE
    union
      {
    char ifrn_name[IFNAMSIZ];   /* Interface name, e.g. "en0".  */
      } ifr_ifrn;

    union
      {
    struct sockaddr ifru_addr;
    struct sockaddr ifru_dstaddr;
    struct sockaddr ifru_broadaddr;
    struct sockaddr ifru_netmask;
    struct sockaddr ifru_hwaddr;
    short int ifru_flags;
    int ifru_ivalue;
    int ifru_mtu;
    struct ifmap ifru_map;
    char ifru_slave[IFNAMSIZ];  /* Just fits the size */
    char ifru_newname[IFNAMSIZ];
    __caddr_t ifru_data;
      } ifr_ifru;
  };
# define ifr_name   ifr_ifrn.ifrn_name  /* interface name   */
# define ifr_hwaddr ifr_ifru.ifru_hwaddr    /* MAC address      */
# define ifr_addr   ifr_ifru.ifru_addr  /* address      */
# define ifr_dstaddr    ifr_ifru.ifru_dstaddr   /* other end of p-p lnk */
# define ifr_broadaddr  ifr_ifru.ifru_broadaddr /* broadcast address    */
# define ifr_netmask    ifr_ifru.ifru_netmask   /* interface net mask   */
# define ifr_flags  ifr_ifru.ifru_flags /* flags        */
# define ifr_metric ifr_ifru.ifru_ivalue    /* metric       */
# define ifr_mtu    ifr_ifru.ifru_mtu   /* mtu          */
# define ifr_map    ifr_ifru.ifru_map   /* device map       */
# define ifr_slave  ifr_ifru.ifru_slave /* slave device     */
# define ifr_data   ifr_ifru.ifru_data  /* for use by interface */
# define ifr_ifindex    ifr_ifru.ifru_ivalue    /* interface index      */
# define ifr_bandwidth  ifr_ifru.ifru_ivalue    /* link bandwidth   */
# define ifr_qlen   ifr_ifru.ifru_ivalue    /* queue length     */
# define ifr_newname    ifr_ifru.ifru_newname   /* New name     */
# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)


Macro magic has been doing the job and luckily there is no ifr_name, etc defined in the user code. Looks like there is no way but to name the elements of this struct as ifr_name, etc?
April 22, 2019
see this other thread for possible solutions too

https://forum.dlang.org/post/anasidaotexgfkyiqmlj@forum.dlang.org
April 22, 2019
On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran wrote:
> What am I doing wrong here?
>
> struct A
> {
>     union B
>     {
>         int bb;
>     }
>     B b;
>     alias aa = B.bb;
> }
>
> void main()
> {
>     A a = A();
>     // a.b.bb = 4; // works
>     a.aa = 4; // fails
> }
>
>
> https://run.dlang.io/is/kXaVy2

You can get the behaviour you want with opDispatch, and generalize it with a mixin template:

mixin template AliasMember(string aliasName, string memberName) {
    ref opDispatch(string name)() if (name == aliasName) {
        return mixin(memberName);
    }
}

struct A {
    union B {
        int bb;
    }
    B b;
    mixin AliasMember!("aa", "b.bb");
}

void main() {
    A a = A();
    a.aa = 4;
}
April 22, 2019
On Monday, 22 April 2019 at 19:57:11 UTC, aliak wrote:
> On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran wrote:
>> What am I doing wrong here?
>>
>> struct A
>> {
>>     union B
>>     {
>>         int bb;
>>     }
>>     B b;
>>     alias aa = B.bb;
>> }
>>
>> void main()
>> {
>>     A a = A();
>>     // a.b.bb = 4; // works
>>     a.aa = 4; // fails
>> }
>>
>>
>> https://run.dlang.io/is/kXaVy2
>
> You can get the behaviour you want with opDispatch, and generalize it with a mixin template:
>
> mixin template AliasMember(string aliasName, string memberName) {
>     ref opDispatch(string name)() if (name == aliasName) {
>         return mixin(memberName);
>     }
> }
>
> struct A {
>     union B {
>         int bb;
>     }
>     B b;
>     mixin AliasMember!("aa", "b.bb");
> }
>
> void main() {
>     A a = A();
>     a.aa = 4;
> }

Works perfect for a single member! Not otherwise.