digitalmars.D.learn - Is it possible to force CTFE?
- Tommi (15/15) Jun 10 2012 Three related questions:
- jerro (15/29) Jun 10 2012 No, but you could wrap it in a template to force it to always
- Tommi (17/19) Sep 27 2012 So, I just realized, I could have just this one convenience
- Timon Gehr (6/20) Jun 10 2012 No there is not. You could use a template that calls a private function
- Tommi (20/22) Jun 10 2012 I was just thinking about a situation where a property
- bearophile (6/8) Sep 27 2012 I am interested in this since some years. I think it's useful,
- Jacob Carlborg (5/11) Sep 27 2012 There's the if (__ctfe) hack. Also using only template parameters will
- bearophile (4/9) Sep 27 2012 This is quite far from what I was discussing about here...
- Tommi (39/39) Sep 28 2012 One use case I can think of for specializing functions based on
- Tommi (6/10) Sep 28 2012 Or, a simpler rule (for both the compiler and the coder):
- Don Clugston (3/11) Oct 01 2012 It has been discussed very often, especially around the time that CTFE
Three related questions: 1) Is there a way to force a function to be always executed at compile time (when it's possible to do so) no matter what context it's called in? 2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant? 3) Does any D compiler currently optimize out a conditional branch which _can_ be evaluated at compile time (but which isn't forced into CTFE)? Like: int getValue(bool b) { return b ? 123 : 456; } //... auto value = getValue(true);
Jun 10 2012
1) Is there a way to force a function to be always executed at compile time (when it's possible to do so) no matter what context it's called in?No, but you could wrap it in a template to force it to always execute at compile time. Of course it could then only be called at compile time.2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?No.3) Does any D compiler currently optimize out a conditional branch which _can_ be evaluated at compile time (but which isn't forced into CTFE)? Like: int getValue(bool b) { return b ? 123 : 456; } //... auto value = getValue(true);DMD, LDC and GDC all do this when compiling with optimizations turned on. They all compile these functions to exactly the same code: auto foo() { return getValue(true); } auto bar() { return 123; }
Jun 10 2012
On Sunday, 10 June 2012 at 10:16:23 UTC, jerro wrote:No, but you could wrap it in a template to force it to always execute at compile time.So, I just realized, I could have just this one convenience template that I can use whenever I want to force an expression to be evaluated at compile-time. Like so: template ct(alias expr) { enum ct = expr; } int fun(int a, int b) { return a + b; } //... and use it like: ct!(fun(1, 2)) That's not *too* inconvenient. Although, best would be a function attribute that would force the compiler to apply ctfe aggressively whenever it can with calls to that function.
Sep 27 2012
On 06/10/2012 09:04 AM, Tommi wrote:Three related questions: 1) Is there a way to force a function to be always executed at compile time (when it's possible to do so) no matter what context it's called in?No there is not. You could use a template that calls a private function at compile time instead. What is your use case?2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?This has been discussed before, but there is not. 1-2) could be introduced later when D gets AST macros.3) Does any D compiler currently optimize out a conditional branch which _can_ be evaluated at compile time (but which isn't forced into CTFE)? Like: int getValue(bool b) { return b ? 123 : 456; } //... auto value = getValue(true);Yes, DMD/GDC/LDC should be able to do this to different extents.
Jun 10 2012
On Sunday, 10 June 2012 at 10:23:09 UTC, Timon Gehr wrote:No there is not. You could use a template that calls a private function at compile time instead. What is your use case?I was just thinking about a situation where a property accessor/mutator methods are not as simple as read/assign value, such as in this silly example: struct Flipping123 { private int m_number = 123; property bool isPositive() { return m_number >= 0; } property void isPositive(bool b) { m_number = b ? 123 : -123; } } //... Flipping123 fl; fl.isPositive = false; // I'd rather not have cond. branching in release mode
Jun 10 2012
Tommi:2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?I am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember people discussing about this much. Bye, bearophile
Sep 27 2012
On 2012-09-27 15:01, bearophile wrote:Tommi:There's the if (__ctfe) hack. Also using only template parameters will force the function to be CTFE. -- /Jacob Carlborg2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?I am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember people discussing about this much.
Sep 27 2012
Jacob Carlborg:This is quite far from what I was discussing about here... Bye, bearophileI am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember people discussing about this much.There's the if (__ctfe) hack. Also using only template parameters will force the function to be CTFE.
Sep 27 2012
One use case I can think of for specializing functions based on whether or not its arguments are compile-time evaluable: // Big container that can't be accessed in constant time: immutable cachedResults = init(); double getResult(<args>) if (areCompileTimeConstants!(<args>) == false) { return cachedResults.at(<args>); } double getResult(<args>) if (areCompileTimeConstants!(<args>) == true) { // Computing the result takes long time ... return computedResult; } Point being that A) cachedResults takes so much memory we don't want to evaluate it at compile-time and bloat the executable, and B) accessing cachedResults takes some non-trivial time, so we don't want to do that at runtime if it can be done at compile-time. Don't know how common this kind of thing would be though. But, that made me think... In a perfect world, I think, the compiler would always evaluate all possible functions at compile-time, given that doing so would produce a smaller (or equal size) executable than what not-evaluating-at-compile-time would produce. For example (assuming the following initialization functions are compile-time evaluable): // The following wouldn't be evaluated at compile time, // because that function call (probably) wouldn't take // as much space in the executable as million ints: int[1_000_000] bigArray = initBigArray(); // The following would be always evaluated at compile time, // because a single int value would take less space in the // executable than the function call: int myValue = initMyValue(); Although, to speed up test compilations, we'd need a compiler flag to disable this "aggressive" CTFE behaviour.
Sep 28 2012
On Friday, 28 September 2012 at 17:52:55 UTC, Tommi wrote:In a perfect world, I think, the compiler would always evaluate all possible functions at compile-time, given that doing so would produce a smaller (or equal size) executable than what not-evaluating-at-compile-time would produce.Or, a simpler rule (for both the compiler and the coder): Have a compiler flag where you set a value (in bytes), and if a function returns a type that's size is not larger than the set value, the compiler would execute all calls to that function at compile-time (if possible).
Sep 28 2012
On 27/09/12 15:01, bearophile wrote:Tommi:It has been discussed very often, especially around the time that CTFE was first introduced. We never came up with a solution.2) Is it possible to specialize a function based on whether or not the parameter that was passed in is a compile time constant?I am interested in this since some years. I think it's useful, but I don't know if it can be implemented. I don't remember people discussing about this much. Bye, bearophile
Oct 01 2012