compile time 'address'

Steven Schveighoffer schveiguy at gmail.com
Thu Nov 29 16:29:00 UTC 2018


On 11/29/18 10:56 AM, Dominic Jones wrote:
> Hello,
> 
> I would like to capture the "address" of variables at compile time. 
> Something not far from this can be done in C++, namely addresses can be 
> compared but not captured (then compared, or whatever).
> 
> I was hoping that it could be done in D, so I wrote something similar to 
> test. It seems that D is more restrictive than C++ in this matter, as 
> even comparison cannot be performed at compile time, as far as I can tell.
> 
> What I wish to do may in principle not be possible, but I am not 
> familiar enough with compilers to know for sure. Also, I am not so 
> familiar with D, so a better transliteration from the C++ example maybe 
> possible and yield something on par or better.
> 
> The reason for wanting to do all this is to find some way of 'baking in' 
> the name of a variable (or some locally unique identifier) into an 
> expression tree node type, facilitating certain expression tree transforms.
> 
> The closest I can get to what I want makes use of mixins, but is not 
> ideal (https://run.dlang.io/is/Fr2b3f).
> 
> 
> C++ (at: https://godbolt.org/z/CLPzGq)
> 
> template<typename T, typename U>
> auto constexpr cmp(T const &t, U const &u)
> {
> /* Preferable, but not possible:
>       auto constexpr ta = &t; // capture
>       auto constexpr ua = &u;
>       return ta == ua;
> */
>    return &t == &u;
> }
> 
> int main()
> {
>    auto c0 = 1;
>    auto c1 = 2;
> 
>    static_assert(cmp(c0, c0));
>    static_assert(!cmp(c0, c1));
> }
> 
> 
> D (at: https://run.dlang.io/is/rf5azp)
> 
> auto cmp(T, U)(const ref T t, const ref U u)
> {
>    return &t == &u;
> }
> 
> void main()
> {
>    auto c0 = 1;
>    auto c1 = 2;
> 
>    // error: "variable c0 cannot be read at compile time"
>    static assert(cmp(c0, c0));
>    static assert(!cmp(c0, c1));
> }

So this is a combination of 2 problems.

1. No you cannot read c0 or c1 at compile time, because they are runtime 
values. You can fix this by changing them to immutable or enum.

2. D doesn't like you taking the address of compile-time values, but the 
error message is really bad.

If I do this:

auto cmp(T, U)(const T t, const U u) // note, no ref
{
   return t == u; // note, change to value not address
}

void main()
{
   immutable c0 = 1; // note change to immutable
   immutable c1 = 2;

   // these now work.
   static assert(cmp(c0, c0));
   static assert(!cmp(c0, c1));
}

If I don't change away from ref, it complains that it can't read c0 or 
c1 at compile time, which clearly is shown to be readable at compile time.

I think the error message should be more like "Cannot use reference to 
this variable at compile-time".

-Steve


More information about the Digitalmars-d mailing list