new annotation or pragma to mark functions that are intended to be only used during compile time

Ilya ilya.yanok at gmail.com
Thu Feb 20 17:42:25 UTC 2025


On Thursday, 20 February 2025 at 15:50:33 UTC, Steven 
Schveighoffer wrote:
> This has been proposed before, and it doesn't require language 
> changes:
>
> ```d
> void foo() {
>    assert(__ctfe);
> }
> ```

Yes, I've seen that. But did it go anywhere? I think on the 
thread I've found there are some discussions with no conclusion.

I also found another proposals that are suggesting introducing a 
new attribute (like I do). But there are also no sign of any 
activity.

I do see a value in not requiring any language changes, but:
1. I'm concerned about doing compile time things based on an 
`assert`, which is a run time thing.
2. I think making an attribute is a bit clearer. Like, asserts 
are supposed to only affect debug builds (well, except for 
`assert(false)`), but I want this new functionality to work in 
release builds too. There is nothing that stops me from 
implementing that, but I don't like that assert's meaning gets 
another exception.

> Basically, this will never work at runtime, only at compile 
> time. It's already used in a lot of D code for things like this.

I agree with the point that existing code could immediately 
benefit from it. That's great. But there is also the second side 
of this medal: that could also render some existing code 
non-compilable. How come? Asserts are run-time, what I'm 
proposing is a static check, so compile time. Static checks are 
usually either unsound or incomplete. I prefer to stay on the 
sound side, so it's doomed to be incomplete, meaning it will 
reject some examples that are working fine with run-time asserts. 
Imagine this:

```d
int ctonly(int x) {
   assert(__ctfe);
   return x+1;
}
int f(int v) {
   if (v < 10) {
     return ctonly(v);
   } else {
     return smth_runtime(v);
   }
}
void main() {
   enum x = f(9); // that's fine, CTFE
   auto y = f(10); // that's also fine, f() doesn't call ctonly()
}
```

This works with runtime assert, but will be rejected by the check.

> The compiler can take this hint as "do not optimize or generate 
> object code for this".

That won't work the same way `assert(__ctfe)` works today, see 
the example above, so you are proposing to change the semantics 
of `assert(__ctfe)`.

> The compiler can also decide at code-generation time to have an 
> error if it has tried to call the function, or maybe the mark 
> gets spread to the next level up?

I think it's better to require the user to be explicit about 
that, otherwise we may end up with skipping code generation of 
`main` :) The only exception is when such function is passed as a 
template parameter, in this case I believe we need to add some 
basic inference to make it usable in practice.

> It can be very straightforward -- if this is not the first 
> runtime statement in the function, then it doesn't get the 
> benefit. It has to be this form.

Yeah, we can take the shortcut in the implementation and only 
look at the first statement, but I'm more concerned about 
changing the semantics.

Why does it have to be this form?



More information about the dip.ideas mailing list