www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - non-constant expression

reply Robby <robby.lansaw gmail.com> writes:
is there a way I can do this in the module scope? I would have thought 
that since everything is known at compile time it would have flew, do I 
need to go about it in a different manner, or?

enum whatever
{
	one,
	two,
	three	
}
int whatever2(int x)
{
	return 1<< x;	
}

const int a = whatever2(whatever.one);
int b = whatever2(whatever.one);

testcode.d(11): Error: non-constant expression (whatever2)(0)
testcode.d(12): Error: non-constant expression (whatever2)(0)
Jan 24 2007
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Robby" <robby.lansaw gmail.com> wrote in message 
news:ep7nbd$1r1i$1 digitaldaemon.com...
 is there a way I can do this in the module scope? I would have thought 
 that since everything is known at compile time it would have flew, do I 
 need to go about it in a different manner, or?

 enum whatever
 {
 one,
 two,
 three }
 int whatever2(int x)
 {
 return 1<< x; }

 const int a = whatever2(whatever.one);
 int b = whatever2(whatever.one);

 testcode.d(11): Error: non-constant expression (whatever2)(0)
 testcode.d(12): Error: non-constant expression (whatever2)(0)

Nope, whatever2 is a function and as such can't be evaluated at compile-time. However, you can use a template instead: enum whatever { one, two, three } template whatever2(int x) { const int whatever2 = 1 << x; } const int a = whatever2!(whatever.one); int b = whatever2!(whatever.one); Note that whatever2 can then not be used as a function; it is always evaluated at compile-time, so you can't do something like void main() { int x; din.readf("%d", x); writefln(whatever!(x)); } because then the const int inside whatever2 will have a non-constant initializer! If you want whatever2 to be a function, you'll have to initialize your globals differently: int whatever2(int x) { return 1 << x; } const int a; int b; static this() { a = whatever2(whatever.one); b = whatever2(whatever.one); } It looks weird, declaring a as a const and then assigning it in the static this(), but that's perfectly legal -- you can assign to constant values once, but that assignment can happen anywhere.
Jan 24 2007
next sibling parent Robby <robby.lansaw gmail.com> writes:
Jarrett Billingsley wrote:
 "Robby" <robby.lansaw gmail.com> wrote in message 
 news:ep7nbd$1r1i$1 digitaldaemon.com...
 is there a way I can do this in the module scope? I would have thought 
 that since everything is known at compile time it would have flew, do I 
 need to go about it in a different manner, or?

 enum whatever
 {
 one,
 two,
 three }
 int whatever2(int x)
 {
 return 1<< x; }

 const int a = whatever2(whatever.one);
 int b = whatever2(whatever.one);

 testcode.d(11): Error: non-constant expression (whatever2)(0)
 testcode.d(12): Error: non-constant expression (whatever2)(0)

Nope, whatever2 is a function and as such can't be evaluated at compile-time. However, you can use a template instead: enum whatever { one, two, three } template whatever2(int x) { const int whatever2 = 1 << x; } const int a = whatever2!(whatever.one); int b = whatever2!(whatever.one); Note that whatever2 can then not be used as a function; it is always evaluated at compile-time, so you can't do something like void main() { int x; din.readf("%d", x); writefln(whatever!(x)); } because then the const int inside whatever2 will have a non-constant initializer! If you want whatever2 to be a function, you'll have to initialize your globals differently: int whatever2(int x) { return 1 << x; } const int a; int b; static this() { a = whatever2(whatever.one); b = whatever2(whatever.one); } It looks weird, declaring a as a const and then assigning it in the static this(), but that's perfectly legal -- you can assign to constant values once, but that assignment can happen anywhere.

cheers for that. haven't seen that error before and was curious, thanks! didn't know about the static this() approach either, though I must admit it really smells like readonly in c# (if I understand d's implementation correctly) Thanks again! Robby
Jan 24 2007
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jarrett Billingsley wrote:
 It looks weird, declaring a as a const and then assigning it in the static 
 this(), but that's perfectly legal -- you can assign to constant values 
 once, but that assignment can happen anywhere. 

I'm pretty sure you can only assign it in the appropriate constructor: static member --> static this() as member of same class/struct/whatever non-static member --> this() [other parameter lists also allowed] module-scope --> static this() at module scope
Jan 24 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Frits van Bommel" <fvbommel REMwOVExCAPSs.nl> wrote in message 
news:ep7qcc$1vrq$1 digitaldaemon.com...
 Jarrett Billingsley wrote:
 It looks weird, declaring a as a const and then assigning it in the 
 static this(), but that's perfectly legal -- you can assign to constant 
 values once, but that assignment can happen anywhere.

I'm pretty sure you can only assign it in the appropriate constructor: static member --> static this() as member of same class/struct/whatever non-static member --> this() [other parameter lists also allowed] module-scope --> static this() at module scope

Yeah, that's right.
Jan 24 2007
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Robby wrote:
[snip]

By the way, it looks like your computer's clock is 2 hours ahead. (or 
timezone setting is wrong)
Jan 24 2007
parent Robby <robby.lansaw gmail.com> writes:
Frits van Bommel wrote:
 Robby wrote:
 [snip]
 
 By the way, it looks like your computer's clock is 2 hours ahead. (or 
 timezone setting is wrong)

during traveling, sigh.. maybe in a few years. thanks
Jan 24 2007