Request for Comment assert(__ctfe)

Johannes Pfau nospam at example.com
Tue Apr 7 11:32:27 UTC 2020


Am Mon, 06 Apr 2020 23:55:59 -0700 schrieb Walter Bright:

> Sounds ok to me, as long as the assert(__ctfe) is the first statement in
> the function body.
> 
> Though I would check the linker map file to see if the linker didn't
> already omit functions that were never called.


Very nice work, Stefan!

This has multiple benefits which have not been mentioned yet:

Yes, the linker might eliminate such functions. In some cases it can't do 
that though, most importantly when building shared libraries. So you may 
end up with useless mixin helpers in shared libraries. Now when we ever 
get a proper export implementation, the linker might be able to remove 
these as well.


As mentioned earlier, no doing codegen might reduce compile times. I 
guess this can be more important for GDC and LDC than for DMD, as we 
spent quite some time in backend optimizer phases. I remember Mike doing 
template heavy embedded stuff which lead to compile times of minutes for 
a hello world with gdc. And IIRC the main issue was the optimizer working 
on hundreds of unused template instances.


And the most important thing: This will vastly improve betterC / nogc 
code:

--------------------
string generateMixin(T)(string b)
{
    assert(__ctfe);
    return T.stringof ~ " " ~ b ~ ";";
}

void main() @nogc
{
    mixin(generateMixin!string("b"));
}
--------------------


Here emitting generateMixin means that at least some of the array 
appending infrastructure needs to be there. If we don't emit the function 
at all, we can probably get rid of all related issues.


However, to also enable these benefits for betterC and not only for 
@nogc, we have to disable the betterC semantic check for such CTFE-only 
functions:

test.d(4): Error: array concatenation of expression "string " ~ b ~ ";" 
requires the GC which is not available with -betterC

@Stefan can you add that to your PR?




Also a comment regarding @ctfe UDA vs assert(__ctfe): Although @ctfe adds 
clutter to function signatures, that actually has it's benefits. With 
@ctfe it would be trivial to check that @ctfe functions are only called 
from other @ctfe functions or a CTFE context instead of letting users run 
into linker errors. Also the information would be available early, I'm 
not sure if the check in semantic3 might be too late for some things 
(e.g. to disable betterC checks)?

This is especially a problem if you link to external libraries where you 
don't have source code: The .di and docs could only include the signature 
and the compiler and user just can't know that this is a ctfe-only 
function. OTOH it doesn't make sense to have only the signature of such a 
function, so you'd probably include the function body for CTFE in the .di 
file anyway. But this would still require the compiler to do an complete 
semantic on all imported modules, only to warn the user if he tried to use 
a @ctfe function in non-ctfe context.


So I guess all things considered I'd prefer @ctfe. But as long as 
whatever syntax is chosen works with -betterC, I'll be very happy either 
way :-)

-- 
Johannes


More information about the Digitalmars-d mailing list