www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can't read a constant value in compile time?

reply Adnan <contact.adnan.02 protonmail.com> writes:
Godbolt: https://godbolt.org/z/SWWOu7

When I write `something!(aNumber)()` and if a number is an 
immutable/enum it should be able to be read at compile time, 
right? Why is this different?

auto fizzbuzz(uint N)() {
     static string accumulate;
     return fizzbuzz!N(accumulate);
}

auto fizzbuzz(uint N)(ref string result) if (N % 3 && N % 5) {
     import std.conv : to;

     result ~= N.to!string ~ "\n";
     return fizzbuzz!(N - 1)(result);
}

auto fizzbuzz(uint N)(ref string result) if (!(N % 15)) {
     result ~= "FizzBuzz\n";
     return fizzbuzz!(N - 1)(result);
}

auto fizzbuzz(uint N)(ref string result) if (!(N % 3) && N % 5) {
     result ~= "Fizz\n";
     return fizzbuzz!(N - 1)(result);
}

auto fizzbuzz(uint N)(ref string result) if (!(N % 5) && N % 3) {
     result ~= "Buzz\n";
     return fizzbuzz!(N - 1)(result);
}

auto fizzbuzz(uint N : 0)(ref string result) {
     return result;
}

void main() {
     import std.stdio : writeln;

     enum lmao = fizzbuzz!50();

     lmao.writeln();
}
Nov 20 2018
next sibling parent Adnan <contact.adnan.02 protonmail.com> writes:
On Tuesday, 20 November 2018 at 18:54:58 UTC, Adnan wrote:
 Godbolt: https://godbolt.org/z/SWWOu7

 When I write `something!(aNumber)()` and if a number is an 
 immutable/enum it should be able to be read at compile time, 
 right? Why is this different?

 auto fizzbuzz(uint N)() {
     static string accumulate;
Also note that removing this `static` seems to work, but produces a massive number of instructions even with -O5. What is the program doing?
Nov 20 2018
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Nov 20, 2018 at 06:54:58PM +0000, Adnan via Digitalmars-d-learn wrote:
 Godbolt: https://godbolt.org/z/SWWOu7
 
 When I write `something!(aNumber)()` and if a number is an
 immutable/enum it should be able to be read at compile time, right?
 Why is this different?
[...] Read this article: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- What do you get if you drop a piano down a mineshaft? A flat minor.
Nov 20 2018
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/20/18 1:54 PM, Adnan wrote:
 Godbolt: https://godbolt.org/z/SWWOu7
 
 When I write `something!(aNumber)()` and if a number is an 
 immutable/enum it should be able to be read at compile time, right? Why 
 is this different?
 
 auto fizzbuzz(uint N)() {
      static string accumulate;
string is not immutable. It's data is immutable, but the array itself can be changed. So it's not readable at compile time. But in any case, you still aren't trying to read it at compile time (i.e. accumulate is not passed into another template as a template parameter).
      return fizzbuzz!N(accumulate);
 }
 
 auto fizzbuzz(uint N)(ref string result) if (N % 3 && N % 5) {
      import std.conv : to;
 
      result ~= N.to!string ~ "\n";
      return fizzbuzz!(N - 1)(result);
 }
 
 auto fizzbuzz(uint N)(ref string result) if (!(N % 15)) {
      result ~= "FizzBuzz\n";
      return fizzbuzz!(N - 1)(result);
 }
 
 auto fizzbuzz(uint N)(ref string result) if (!(N % 3) && N % 5) {
      result ~= "Fizz\n";
      return fizzbuzz!(N - 1)(result);
 }
 
 auto fizzbuzz(uint N)(ref string result) if (!(N % 5) && N % 3) {
      result ~= "Buzz\n";
      return fizzbuzz!(N - 1)(result);
 }
 
 auto fizzbuzz(uint N : 0)(ref string result) {
      return result;
 }
 
 void main() {
      import std.stdio : writeln;
 
      enum lmao = fizzbuzz!50();
Here you are trying to *execute* fizzbuzz at compile time. So it tries to interpret the runtime function at compile time (which should work). However, static data doesn't exist in CTFE I don't think, so that's why it works when you remove static. Why is it generating so much code? Because you are using templates, and even templates you only use at compile time STILL generate and get included in the binary (something I think D could probably fix). Instead of using templates, just write it as runtime functions, and then do: enum lmao = fizzbuzz(50); It will go much better. -Steve
Nov 20 2018