lazy evaluation of logical operators in enum definition

Jacob Carlborg doob at me.com
Tue Apr 17 06:54:23 UTC 2018


On Monday, 16 April 2018 at 05:57:01 UTC, Shachar Shemesh wrote:
> Consider the following program:
>
> struct S1 {
>     enum member = 3;
> }
>
> struct S2 {
>     enum member = 2;
> }
>
> struct S3 {
> }
>
> enum prop(T) = __traits(hasMember, T, "member") && T.member==3;
>
> pragma(msg, prop!S1);
> pragma(msg, prop!S2);
> pragma(msg, prop!S3);
>
> When compiled, it produces:
> true
> false
> test.d(12): Error: no property member for type S3
> test.d(16): Error: template instance `test.prop!(S3)` error 
> instantiating
> test.d(16):        while evaluating pragma(msg, prop!(S3))
>
> If I change the definition of "prop" to:
> template prop(T) {
>     static if( __traits(hasMember, T, "member") && T.member==3 )
>         enum prop = true;
>     else
>         enum prop = false;
> }
>
> then everything compiles as expected.
>
> It seems that the && evaluation does not stop when the first 
> false is found.

I think the issue is better illustrated with a function:

bool prop(T)()
{
     if (__traits(hasMember, T, "member"))
     {
         if (T.member == 3)
             return true;
     }

     return false;
}

In this function there's no way to tell if the function is going 
to be executed at compile time or at runtime. Therefore the 
semantics of the whole function need to be valid. Replacing the 
`if` with a `static if` would solve the problem, as you 
mentioned. This works because the semantic analysis of `static 
if` and CTFE evaluation of a function occurs at different phases 
in the compiler. This post explains this better and in more 
detail [1]. The issue is that the compiler will do the semantic 
analysis of `T.member` before it has run CTFE or constant folding 
on the expression.

Although, one could argue that in your case it's clear that the 
expression only will be evaluated at compile time, but that's not 
how the compiler works currently.

[1] 
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time

--
/Jacob Carlborg


More information about the Digitalmars-d mailing list