Compiler error · error CS0163

Control cannot fall through from one case label to another

A case did its work and then… kept going into the next case. In C and C++ that's legal and caused decades of bugs; in C# the compiler simply refuses. Every non-empty case must end with break;, return;, or throw;.

See it happen

int d = 1;
switch (d)
{
    case 1:
        Console.WriteLine("one");
        // no break — control would "fall through" into case 2
    case 2:
        Console.WriteLine("two");
        break;
}
int d = 1;
switch (d)
{
    case 1:
        Console.WriteLine("one");
        break;               // hand control back — done
    case 2:
        Console.WriteLine("two");
        break;
}

But you probably wanted stacked labels

The thing people usually mean when they "fall through" is several values sharing one body. That's legal — stack the labels with nothing between them:

void Classify(int day)
{
    switch (day)
    {
        case 6:
        case 7:                      // 6 and 7 share this body — no code between labels
            Console.WriteLine("weekend");
            break;
        default:
            Console.WriteLine("weekday");
            break;
    }
}

Classify(7);
Classify(3);

The rule is precise: empty labels may stack (fall-through of nothing); a label with any code must end the block itself.

Why C# is stricter than C++ — and why that's good

In C++, forgetting break silently executes the next case's code. The famous Apple goto fail bug was exactly this shape. C#'s designers made the missing break a compile-time error, trading a little convenience for the elimination of a whole bug class. When you hit CS0163, the compiler isn't nagging — it's the language keeping a 50-year-old trap shut.

Frequently asked

How do I fix error CS0163 in C#?

In C and C++ a missing break silently runs the next case — the shape of famous bugs like Apple's goto fail. C# makes it a compile error; empty stacked labels remain legal for shared bodies.

Why does C# forbid switch fall-through?

undefined

Endings the compiler accepts

int Apply(char op, int a, int b)
{
    switch (op)
    {
        case '+':
            return a + b;              // return ends the case — no break needed
        case '*':
            return a * b;
        default:
            throw new Exception("unknown operator");   // throw ends it too
    }
}

Console.WriteLine("result: " + Apply('*', 2, 4));

break exits the switch; return exits the whole method; throw exits explosively. Any of the three satisfies the rule — but plain "running off the end of a case" never will.

Checklist