alias fails to compile
Arun Chandrasekaran
aruncxy at gmail.com
Mon Apr 22 15:43:29 UTC 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?
More information about the Digitalmars-d-learn
mailing list