Thread overview
Structs and CTFE
Jul 04, 2010
Jonathan M Davis
Jul 04, 2010
Simen kjaeraas
Jul 04, 2010
bearophile
July 04, 2010
Okay, as I understand it, you can't yet use classes with CTFE. As TDPL puts it: "Alocating class objects and memory in general is not allowed." But my question is "What about structs?"

I'm trying to create an enum of a struct type. The compiler insists that I create an opCmp() for the struct (which makes sense, I suppose, since normally enums are compareable), but even with opCmp() defined, the compiler appears to be complaining about my constructors as well as opCmp(), saying that they can't be evaluated at compile time.

For instance, if I were to write a program that looks like this

struct S
{
    this(string phrase, int num)
    {
        this.phrase = phrase;
        this.num = num;
    }

    int opCmp(const ref S rhs)
    {
        int phraseCmp = phrase.opCmp(rhs.phrase);

        if(phrase != 0)
            return phraseCmp;

        if(num < rhs.num)
            return -1;
        else if(num > rhs.num)
            return 1;

        return 0;
    }

    string phrase;
    int    num;
}

enum E : S {a = S("hello", 1),
            b = S("goodbye", 45),
            c = S("world", 22)};

void main()
{


then I get the following errors

t.d(28): Error: variable __ctmp1 cannot be read at compile time
t.d(28): Error: cannot evaluate __ctmp1.this("hello",1) at compile time
t.d(28): Error: cannot evaluate __ctmp1.this("hello",1) at compile time
t.d(29): Error: cannot evaluate __ctmp2.this("goodbye",45) at compile time
t.d(29): Error: cannot evaluate __ctmp2.this("goodbye",45) at compile time
t.d(28): Error: cast(const(S))__ctmp1.this("hello",1) is not an lvalue
t.d(29): Error: cannot evaluate __ctmp2.this("goodbye",45) at compile time
t.d(29): Error: cannot evaluate
__ctmp2.this("goodbye",45).opCmp(cast(const(S))__ctmp1.this("hello",1)) at
compile time
t.d(29): Error: Integer constant expression expected instead of
__ctmp2.this("goodbye",45).opCmp(cast(const(S))__ctmp1.this("hello",1)) < 0
t.d(28): Error: cast(const(S))__ctmp1.this("hello",1) is not an lvalue
t.d(29): Error: cannot evaluate __ctmp2.this("goodbye",45) at compile time
t.d(29): Error: cannot evaluate
__ctmp2.this("goodbye",45).opCmp(cast(const(S))__ctmp1.this("hello",1)) at
compile time
t.d(29): Error: Integer constant expression expected instead of
__ctmp2.this("goodbye",45).opCmp(cast(const(S))__ctmp1.this("hello",1)) > 0
t.d(30): Error: cannot evaluate __ctmp3.this("world",22) at compile time
t.d(30): Error: cannot evaluate __ctmp3.this("world",22) at compile time
t.d(28): Error: cast(const(S))__ctmp1.this("hello",1) is not an lvalue
t.d(30): Error: cannot evaluate __ctmp3.this("world",22) at compile time
t.d(30): Error: cannot evaluate
__ctmp3.this("world",22).opCmp(cast(const(S))__ctmp1.this("hello",1)) at compile
time
t.d(30): Error: Integer constant expression expected instead of
__ctmp3.this("world",22).opCmp(cast(const(S))__ctmp1.this("hello",1)) < 0
t.d(28): Error: cast(const(S))__ctmp1.this("hello",1) is not an lvalue
t.d(30): Error: cannot evaluate __ctmp3.this("world",22) at compile time
t.d(30): Error: cannot evaluate
__ctmp3.this("world",22).opCmp(cast(const(S))__ctmp1.this("hello",1)) at compile
time
t.d(30): Error: Integer constant expression expected instead of
__ctmp3.this("world",22).opCmp(cast(const(S))__ctmp1.this("hello",1)) > 0


Is it not presently possible to use structs for enums, or to use them in CTFE in general? Or am I just doing something wrong?

- Jonathan M Davis
July 04, 2010
Jonathan M Davis <jmdavisprog@gmail.com> wrote:

> Is it not presently possible to use structs for enums

I believe this is the case, yes.

There are ways to do things that are similar, of course:

struct E { //Namespace, as D lacks those
    struct S {
        this( string phrase, int num ) {
            this.phrase = phrase;
            this.num = num;
        }
        string phrase;
        int    num;
    }
    enum a = S("hello", 1);
    enum b = S("goodbye", 45);
    enum c = S("world", 22);
}

-- 
Simen
July 04, 2010
std.string.cmp probably calls strcmp that I don't think can run in CTFE. I am not sure CTFE accepts arguments by ref opCmp(const ref S rhs) and probably there are other problems I don't know about...

Bye,
bearophile