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