I get a compile error when I try to compile this code:
import std.regex;
enum truth = "baba".matchFirst(ctRegex!`[ab]+$`) ? true : false;
void main() {}
/usr/local/Cellar/dmd/2.067.1/include/d2/std/regex/package.d(671): Error: malloc cannot be interpreted at compile time, because it has no available source code
How to get around this?
You can't, the regex can be compiled at compile time, but not run. You'll have to write the match some other way, maybe a combination of indexOf or other simpler functions. (The reason isn't because regex is too complicated, it is actually because it internally calls
malloc
for efficiency, which is not supported at compile time since it is an external C function.)Understanding
ctRegex
needs some explanation Phobos' regular expression engine. It works in two steps: given a regular expression, it first compiles that into some bytecode, then to match it on a string, it runs that code.In the ordinary
regex
, both those steps happen at runtime. When you construct the regex object, it compiles it into the bytecode. Then, when you match on a string, it runs that code.With
ctRegex
, the first part happens at compile time, but the second part still happens at runtime. So it compiles the regex into bytecode when the D is compiled... then shoves that bytecode through the rest of the D compiler to be optimized to fully native code. So that's the benefit it can offer. (BTW the difference often doesn't really matter, you should benchmark for your input strings to see which one is better.)Normally, CTFE (compile-time function evaluation) means runtime code can be run at compile time too, but only if the source is available. That's not the case for
malloc
which is why the error says that.So the answer will depend on just what your regex is. You'll probably want to simplify it and rewrite it in terms of other string and/or std.algorithm functions.
...or rewrite the std.regex source code to get rid of those malloc calls. Replace them with
new
andif(_ctfe)
to start. I've tried doing this before though, and unless the code has been refactored since then, you'll just hit another problem: for runtime performance, std.regex also uses things like unions, which also aren't supported in ctfe... you'd have to rewrite a bunch of it and be careful not to compromise the runtime performance in the process.Probably easier to just handle your specific case with other functions.