[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Paul Backus changed: What|Removed |Added CC||maxha...@gmail.com --- Comment #13 from Paul Backus --- *** Issue 20086 has been marked as a duplicate of this issue. *** --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #12 from Adam D. Ruppe --- (In reply to Steven Schveighoffer from comment #9) > Except this is not the problem. The CTFE part DOES compile. h, it is the problem that brought me to this bug. private string makefoo() { if(__ctfe) { string a = "b"; a ~= "c\0"; return a; } assert(0); } enum foo = makefoo(); extern(C) int main() { import core.stdc.stdio; printf("%s", foo.ptr); return 0; } Here that private function is obviously intended to be CTFE only - the `private` and `if(__ctfe)` make that extremely clear to a human reader, but the compiler doesn't get the hint. We could also do a like `pragma(ct_only)` maybe just I was hoping this pattern would work since it is in the existing language. But nope :( --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #11 from Steven Schveighoffer --- (In reply to ZombineDev from comment #5) > I guess the trickiest problem to solve is what to do about is(typeof({ code; > })) and __traits(compiles, { code; }). Allowing those constructs to yield > true while containing non-betterc code would lead to logical contradictions. > Disallowing betterc code in such speculative contexts, while allowing it in > CTFE context would be strange. When trying to test stuff surrounding this, I'll note that a betterC error seems to kill the compilation when used inside __traits(compiles). This prints nothing and produces no binary: extern(C) void main() { int[] arr; pragma(msg, __traits(compiles, arr.idup)); } --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #10 from Steven Schveighoffer --- Ooooh, I just had an idea. Consider the template that is causing issues _dup. What if we did this: version(D_BetterC) extern(C) void _dup_UNAVAILABLE_IN_BETTERC(); private U[] _dup(T, U)(T[] a) // pure nothrow depends on postblit { if (__ctfe) { /* ctfe code */ } version(D_BetterC) { _dup_UNAVAILABLE_IN_BETTERC(); return U[].init; } else: // normal implementation that uses typeid } This defers the error to the linker, but with the message identifying which function is causing the problem. We can probably make an easy mixin to do this wherever needed. In essence this is a compiler error, with a "funky" but albeit legible message. But this does change idup to return true for __traits(compiles). Is that a problem? I'd say no. Use the version(D_BetterC) instead of __traits(compiles). Aaand, it doesn't work. Using a template at compile time for some reason makes the compiler want to link in the symbol. I think there is no way to make this work unless the compiler is smarter about what it used at compile time vs. runtime. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #9 from Steven Schveighoffer --- (In reply to Adam D. Ruppe from comment #8) > My view is that the code compiles just fine. Just without druntime linked in > or generated typeinfo, or whatever it depends on at run time, it will not > link. > > The -betterC switch tries to detect these these would-be linker errors and > report them ahead of time, in the compile step, for more consistent and > user-friendly errors. Right, this is my view too. > Since an `if(__ctfe)` branch (or `mixin` or `pragma(msg)` or any other > unambiguously* compile-time only area) is never actually involved in code > generation, that linker error will never actually happen... and the compiler > *should* know that and not cause the ahead-of-time compile error eiter. Except this is not the problem. The CTFE part DOES compile. It's the part that's outside that doesn't (in fact typeid(x) does not compile during CTFE). So how do you "compile" that, and only allow it to run at compile time? That's why this is hard. Any solution for detecting druntime usage is not going to be perfect. For example, this doesn't have compile errors but linker errors (with -betterC): import core.thread; import core.time; extern(C) void main() { Thread.sleep(1.seconds); } And of course, __traits(compiles) is going to say YES to this. So it is indeed a gray area. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #8 from Adam D. Ruppe --- My view is that the code compiles just fine. Just without druntime linked in or generated typeinfo, or whatever it depends on at run time, it will not link. The -betterC switch tries to detect these these would-be linker errors and report them ahead of time, in the compile step, for more consistent and user-friendly errors. Since an `if(__ctfe)` branch (or `mixin` or `pragma(msg)` or any other unambiguously* compile-time only area) is never actually involved in code generation, that linker error will never actually happen... and the compiler *should* know that and not cause the ahead-of-time compile error eiter. * __traits(compiles) (and is(typeof())) is a grey area. Technically it isn't generating code at all and thus should not generate a linker error, and thus not generate the betterC error but given how it is used in practice I think it should assume the stuff inside WILL be used for codegen and thus return false in these cases. But when in doubt, I say `-betterC` should aim to give the same end result as `-defaultlib=` just with compile errors instead of linker undefined symbol errors. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #7 from Steven Schveighoffer --- (In reply to ZombineDev from comment #5) > I guess the trickiest problem to solve is what to do about is(typeof({ code; > })) and __traits(compiles, { code; }). Allowing those constructs to yield > true while containing non-betterc code would lead to logical contradictions. > Disallowing betterc code in such speculative contexts, while allowing it in > CTFE context would be strange. This is a good point. CTFE is hard because it still needs to compile, even though in this case you won't actually run that code. I would say that functions that are not going into the object symbol table can be compiled and run for CTFE only. If you do try to refer to that symbol during runtime, then throw the error. I don't know how hard this is to do, but it seems possible. possibly another answer is to revert the binding to druntime idup in betterC mode (obviously this worked before). --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 --- Comment #6 from Adam D. Ruppe --- I think my proposal would be that *specifically* the `if(__ctfe)` construct overrides the betterC checks, since that can be easily factored out. Just like how we can write --- int* do_something() { if(__ctfe) { return new int; } else { return cast(int*) malloc(int.sizeof); } } enum e = *do_something(); --- today (which works in real D, including without linking druntime btw), which bypasses the normal "malloc cannot be evaluated at compile time), we could conceivably use it in the other direction to allow something in a CT context that isn't allowed in a RT context. I'm not sure how to write that in spec language... it might be able to just say specifically that betterC's restrictions do not apply inside that specific ast node and like specifically hack the hack that is betterC. I think that would be fine with `__traits(compiles)` as well. The `if(__ctfe)` switch keeps everything compiling the same way - it is specifically a runtime branch in terms of formal semantics. So the compiles thing passes because that if branch is encapsulated still. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 ZombineDev changed: What|Removed |Added CC||petar.p.ki...@gmail.com --- Comment #5 from ZombineDev --- I guess the trickiest problem to solve is what to do about is(typeof({ code; })) and __traits(compiles, { code; }). Allowing those constructs to yield true while containing non-betterc code would lead to logical contradictions. Disallowing betterc code in such speculative contexts, while allowing it in CTFE context would be strange. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Steven Schveighoffer changed: What|Removed |Added CC||schvei...@yahoo.com See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=20613 --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Adam D. Ruppe changed: What|Removed |Added CC||destructiona...@gmail.com --- Comment #4 from Adam D. Ruppe --- idup is found in betterC, just the compiler refuses to run it. The betterC restrictions should not apply while executing in a compile time context at all. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Les De Ridder changed: What|Removed |Added CC||dl...@lesderid.net --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Nathan S. changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=19561 --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Walter Bright changed: What|Removed |Added CC||bugzi...@digitalmars.com --- Comment #3 from Walter Bright --- This particular error is happening because the definition of idup() in object.d is versioned out when BetterC is on, so ctfe cannot find it. There's not an obvious solution to this. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Radu Racariu changed: What|Removed |Added CC||radu.raca...@gmail.com --- Comment #2 from Radu Racariu --- See https://github.com/dlang/dmd/pull/8253 for related discussion. This needs a fix. --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Sebastiaan Koppe changed: What|Removed |Added CC||m...@skoppe.eu --- Comment #1 from Sebastiaan Koppe --- I have similar issues. Most things from phobos don't work in CTFE when compiling with betterC (same error in both dmd and ldc). --- void main() { import std.uni : toLower; pragma(msg,"asdfBsdf".toLower); } --- --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Илья Ярошенко changed: What|Removed |Added Keywords||rejects-valid --
[Issue 19268] BetterC turns off DRuntime for CTFE
https://issues.dlang.org/show_bug.cgi?id=19268 Илья Ярошенко changed: What|Removed |Added Keywords||betterC --