Thread overview
non-constant expression
Jan 24, 2007
Robby
Jan 24, 2007
Robby
Jan 24, 2007
Frits van Bommel
Jan 24, 2007
Frits van Bommel
Jan 24, 2007
Robby
January 24, 2007
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)
January 24, 2007
"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.


January 24, 2007
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. 
> 
> 
porting a couple of c libs over and got caught on that in a header, 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
January 24, 2007
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
January 24, 2007
Robby wrote:
[snip]

By the way, it looks like your computer's clock is 2 hours ahead. (or timezone setting is wrong)
January 24, 2007
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)
if only computers were gps enabled and synced clocks due to location during traveling, sigh.. maybe in a few years. thanks
January 25, 2007
"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.