Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 04, 2009 At compile time | ||||
---|---|---|---|---|
| ||||
D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. This little C++ program compiles correctly with G++: // C++ code #include <math.h> #include <stdio.h> struct V3 { double x, y, z; V3(const double a, const double b, const double c) : x(a), y(b), z(c) {} V3 operator*(const double d) const { return V3(x * d, y * d, z * d); } V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; } double magsqr() const { return dot(*this); } }; const V3 v(V3(-0.5, -0.65, 0.9).norm()); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; } But similar D2 program produces, with DMD v.2.031: test.d(12): Error: non-constant expression (V3(1,2,3)).norm() // D2 code import std.math, std.c.stdio; struct V3 { double x, y, z; V3 opMul(double d) { return V3(x * d, y * d, z * d); } V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } double magsqr() { return dot(this); } } const V3 v = V3(1.0, 2.0, 3.0).norm(); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; } Do you know why? Can the D2 compiler modified/improved to allow this? Bye and thank you, bearophile |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Tue, Aug 4, 2009 at 7:57 PM, bearophile<bearophileHUGS@lycos.com> wrote: > D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. > > This little C++ program compiles correctly with G++: > > // C++ code > #include <math.h> > #include <stdio.h> > > struct V3 { > double x, y, z; > V3(const double a, const double b, const double c) : x(a), y(b), z(c) {} > V3 operator*(const double d) const { return V3(x * d, y * d, z * d); } > V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } > double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; } > double magsqr() const { return dot(*this); } > }; > > const V3 v(V3(-0.5, -0.65, 0.9).norm()); > > int main() { > printf("%f %f %f\n", v.x, v.y, v.z); > return 0; > } > > > But similar D2 program produces, with DMD v.2.031: > test.d(12): Error: non-constant expression (V3(1,2,3)).norm() > > // D2 code > import std.math, std.c.stdio; > > struct V3 { > double x, y, z; > V3 opMul(double d) { return V3(x * d, y * d, z * d); } > V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } > double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } > double magsqr() { return dot(this); } > } > > const V3 v = V3(1.0, 2.0, 3.0).norm(); > > int main() { > printf("%f %f %f\n", v.x, v.y, v.z); > return 0; > } > > Do you know why? I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function. > Can the D2 compiler modified/improved to allow this? It sure would be nice. |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley:
> I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.
I see. It's a significant limitation, that curiously G++ doesn't share.
I have tried to follow your suggestion, but so far with not too much luck, even essentially pulling out all methods of that struct :-)
Thank you,
bye,
bearophile
|
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Tue, Aug 4, 2009 at 10:13 PM, bearophile<bearophileHUGS@lycos.com> wrote: > Jarrett Billingsley: >> I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function. > > I see. It's a significant limitation, that curiously G++ doesn't share. I don't think your C++ code is doing what you think it's doing. I'm pretty sure the C++ code: const V3 v(V3(-0.5, -0.65, 0.9).norm()); is equivalent to the following D code: const V3 v; static this() { v = V3(-0.5, -0.65, 0.9).norm(); } C++ has static initialization that occurs before main() too. It's just.. hidden. |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> I don't think you can call struct methods at compile-time. Kind of
> lame, I know. Try making norm a free function.
>
>> Can the D2 compiler modified/improved to allow this?
>
> It sure would be nice.
In fact the D1 compiler should support it too.
BTW a few of the restrictions on CTFE will be removed in the next release.
|
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | Don wrote: > Jarrett Billingsley wrote: >> I don't think you can call struct methods at compile-time. Kind of >> lame, I know. Try making norm a free function. >> >>> Can the D2 compiler modified/improved to allow this? >> >> It sure would be nice. > > In fact the D1 compiler should support it too. > BTW a few of the restrictions on CTFE will be removed in the next release. This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation or are they "undocumented" restrictions, i.e. bugs? -Lars |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley: >C++ has static initialization that occurs before main() too. It's just.. hidden.< I see. I have to learn more about C++. Thank you. ------------------ Lars T. Kyllingstad: >This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation < That list has a point regarding what I was trying to do: >4. the function may not be a non-static member, i.e. it may not have a this pointer< It's true regarding stucts used as values too, and not just classes... Bye, bearophile |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile escribió:
> Jarrett Billingsley:
>> C++ has static initialization that occurs before main() too. It's just.. hidden.<
>
> I see. I have to learn more about C++. Thank you.
>
> ------------------
> Lars T. Kyllingstad:
>
>> This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation <
>
> That list has a point regarding what I was trying to do:
>> 4. the function may not be a non-static member, i.e. it may not have a this pointer<
> It's true regarding stucts used as values too, and not just classes...
It would be nice if the compiler could say so: "I can't evaluate it because you are using a this pointer". With other words, but much more useful than "non-constant expression".
|
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | *On Wed, Aug 5, 2009 at 7:23 AM, Ary Borenszweig<ary@esperanto.org.ar> wrote: > bearophile escribió: >> >> Jarrett Billingsley: >>> >>> C++ has static initialization that occurs before main() too. It's just.. >>> hidden.< >> >> I see. I have to learn more about C++. Thank you. >> >> ------------------ >> Lars T. Kyllingstad: >> >>> This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation < >> >> That list has a point regarding what I was trying to do: >>> >>> 4. the function may not be a non-static member, i.e. it may not have a this pointer< >> >> It's true regarding stucts used as values too, and not just classes... > > It would be nice if the compiler could say so: "I can't evaluate it because you are using a this pointer". With other words, but much more useful than "non-constant expression". Yes, oh my God, this is the main reason I don't use CTFE: debugging them is virtually impossible, and the compiler does nothing to help there. |
August 05, 2009 Re: At compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile Attachments: | bearophile wrote: > D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. > > This little C++ program compiles correctly with G++: > > // C++ code > #include <math.h> > #include <stdio.h> > > struct V3 { > double x, y, z; > V3(const double a, const double b, const double c) : x(a), y(b), z(c) {} > V3 operator*(const double d) const { return V3(x * d, y * d, z * d); } > V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } > double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; } > double magsqr() const { return dot(*this); } > }; > > const V3 v(V3(-0.5, -0.65, 0.9).norm()); > > int main() { > printf("%f %f %f\n", v.x, v.y, v.z); > return 0; > } <snip> > Do you know why? > Can the D2 compiler modified/improved to allow this? > > Bye and thank you, > bearophile Not really relevant to the compile time issue but, your d2 code should be: import std.math; import std.stdio; struct V3 { double x, y, z; this(double _x, double _y, double _z) { x = _x; y = _y; z = _z; } V3 opMul(double d) const { return V3(x * d, y * d, z * d); } V3 norm() const { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) const { return x * v.x+y * v.y + z * v.z; } double magsqr() const { return dot(this); } } const V3 v; static this() { v = V3(1.0, 2.0, 3.0).norm(); } int main() { writefln("%f %f %f", v.x, v.y, v.z); writefln("%f", v.magsqr()); return 0; } This produces identical behavior to the c++ example. As Jarrett said, in c++ you have hidden runtime initialisation, which is made explicit in D. Having it work at compile time would be sweet. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk |
Copyright © 1999-2021 by the D Language Foundation