Limits in cases of switching in case of range

I am trying to include UTF-8 ids in a case switch, but I am getting this error:

Error: there were 399 cases, which is over 256 cases in the range case

D code:

    switch(value)
    {
        case 'a': ..  case 'z':
        case 'A': ..  case 'Z':
        case 0xC0: .. case 0x24F:

      

Why did the compiler impose such a restriction? for optimal purposes? can i overcome it?

+3


source to share


3 answers


Doing this as an answer to get more space.

The limitation you see here is missing from the spec http://dlang.org/statement and ONLY applies to CaseRangeStatements in the compiler: src / dmd / statement.c line 3437 per version I have:

if (lval - fval > 256)
{   error("had %llu cases which is more than 256 cases in case range", lval - fval);
    lval = fval + 256;
}

      

As a result, the fix would be to split this range into several parts and put them next to each other:

        switch(value)
{
    case 'a': ..  case 'z':
    case 'A': ..  case 'Z':
    case 0xC0: .. case 0x14F: // this compiles
    case 0x150: .. case 0x24F: // since it is broken up

      



Then you handle them the same way.

The compiler source doesn't say why it has this check, but the github history says it was fixed in response to this bug: https://issues.dlang.org/show_bug.cgi?id=3139

[s] So the compiler has detailed implementation to avoid infinite loop. [/ s]

EDIT: actually, the 256 check was before, I misread the patch, Don added a check to it. It looks like 256 pieces predate github, so I don't know why it was added on purpose, but I'm still pretty sure it's related to these loop and memory issues, and compiler details and bugs.

+5


source


An alternative way to get rid of the constraint is to use a delegate array and choose which method to call using a symbol as a selector. Then your switch will look something like this:



void main(string args[])
{
    alias caseProc = void delegate();
    caseProc[1024] callTable;

    void numberProc(){}
    void latinProc(){}
    void otherProc(){}

    for(auto i = 0; i < callTable.length; i++)
    {
        if (i >= '0' && i <= '9')
            callTable[i] = &numberProc;
        else if ((i >= 'a' && i <= 'z') | (i >= 'A' && i <= 'Z'))
            callTable[i] = &latinProc;
        else
            callTable[i] = &otherProc;
    }
}

      

+2


source


The switch in D can only hold up to 256 cases. You have to change the whole way of doing it.

if (value >= 'a' && value <= 'z')
{
    // ...
}
else if (value >= 'A' && value <= 'Z')
{
    // ...
}
else if (value >= 0xC0 && value <= 0x24F)
{
    // ...
}

      

Or so if you want to handle all cases the same way.

if (value >= 'a' && value <= 'z' || value >= 'A' && value <= 'Z' || value >= 0xC0 && value <= 0x24F)
{
  // ...
}

      

0


source







All Articles