www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this an auto ref bug?

reply Andrej Mitrovic <none none.none> writes:
import std.traits;

void main()
{
    const wchar* t;
    unqual(t);
}

auto ref unqual(T)(ref T value)
{
    return cast(Unqual!T)value;
}

I've attempted to create myself an unqual function which could for example do a
cast from const char* to char*. The above won't work though:
test.d(14): Error: variable test.unqual!(const(char*)).unqual.value cannot
modify const

It does work if I only use auto:
auto unqual(T)(ref T value)
{
    return cast(Unqual!T)value;
}

But that creates an rvalue. 

I wanted to use such a function to avoid doing explicit casts to get an
unqualified type. For example a C function might be prototyped as:

foo(char* input);

You can't pass a const char* here, so you would have to either cast the type:
const char* str;
foo(cast(char*)str);

Or you would modify the prototype to:
foo(const(char)* input);
foo(str);  // now ok

The second choice is probably the best, since this specific C function would
not actually modify the input. But I thought having an "unqual" function would
be handy, so I could use:

foo(unqual(str));
Apr 25 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
 import std.traits;
 
 void main()
 {
     const wchar* t;
     unqual(t);
 }
 
 auto ref unqual(T)(ref T value)
 {
     return cast(Unqual!T)value;
 }
 
 I've attempted to create myself an unqual function which could for example
 do a cast from const char* to char*. The above won't work though:
 test.d(14): Error: variable test.unqual!(const(char*)).unqual.value cannot
 modify const
 
 It does work if I only use auto:
 auto unqual(T)(ref T value)
 {
     return cast(Unqual!T)value;
 }
 
 But that creates an rvalue.
 
 I wanted to use such a function to avoid doing explicit casts to get an
 unqualified type. For example a C function might be prototyped as:
 
 foo(char* input);
 
 You can't pass a const char* here, so you would have to either cast the
 type: const char* str;
 foo(cast(char*)str);
 
 Or you would modify the prototype to:
 foo(const(char)* input);
 foo(str);  // now ok
 
 The second choice is probably the best, since this specific C function
 would not actually modify the input. But I thought having an "unqual"
 function would be handy, so I could use:
 
 foo(unqual(str));
Okay. First off, T does _not_ include the ref. So, Unqual!T is not going to be a ref (and it doesn't look like you can cast to ref either, which does make a fair bit of sense). So, the result of the cast is a temporary, and you can't have a ref to a temporary, so it's illegal to return auto ref from the function. auto works because then the return type is just wchar* - there's no ref there. I really don't think that it works to change the type of a ref. - Jonathan M Davis
Apr 25 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Oh I've just realized I was being a little silly here. I don't need
ref for pointers. Essentially I was looking to make this:

auto ref unqual(T)(ref T value)
{
   return cast(Unqual!T)value;
}

do this:

char* unqual(const char* value)
{
   return cast(char*)value;
}

Except to make it work for any type. Which is why I thought auto ref
would do it. :)
Apr 25 2011