1

Found this construction while reviewing some code and I was expecting it to not compile at all, tbh. Any reasons why this is permitted?

int i = 0;
switch (i)
{
    case 0:
        int k = 0;
        break;
    case 1:
        k = 1;
        break;
}

Edit: even more strange, adding Console.Out.WriteLine(k); after case 1: gives error use of unassigned variable 'k'...

General Grievance
  • 4,555
  • 31
  • 31
  • 45
mBardos
  • 2,872
  • 1
  • 19
  • 16
  • What part does bother you? `k = 1;`? – SᴇM Feb 25 '22 at 12:30
  • I found it surprising, that `k` wasn't even declared in the `case 1` "block", I expected a compile error for that. – mBardos Feb 25 '22 at 12:59
  • 2
    It is legal because it is specifically documented to be legal. In [C# Specification 12.8.3 The Switch Statement](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#1283-the-switch-statement) you can scroll down a bit and find this sentence: "The scope of a local variable or constant declared in a switch block is the switch block.". The "switch block" is the entire outer `{ ... }` part of the switch statement. The individual sub-"blocks" for each case are called "switch sections". As to *why* they decided to do that, quite difficult to answer. – Lasse V. Karlsen Feb 25 '22 at 13:16
  • 1
    Th historical reason for it is probably that it's a legacy from C/C++ where `case` fall-through was allowed – Charlieface Feb 25 '22 at 13:26

1 Answers1

-1

Any reasons why this is permitted?

We probably cannot say for certain: The essential answer is "because it is" or "because your reasons for thinking it shouldn't be differ with the thinking of those who designed the language" but we can't really speak to questions like "what were Microsoft thinking when they designed it such that...", unless perhaps someone is one of the privileged few to have sat in that design meeting and can be authoritative

SharpLab.io will, however, tell you what happens under the hood; it compiles then decompiles your code and shows you the result, so you can get an idea of what your code was transformed into by the compiler:

enter image description here

Note: swapped your numbers for other, non-default, ones so that identification of what was what can be maintained after the compiler changes the names

A lot of the code you write is syntactic sugar for something else; here you can see your int k isn't buried within the switch, scoped to only "within the first case", but transformed into something else entirely.. It's thus legal C# because nothing prevents it not being, and you can rationalize that in a way that will help you remember it.. In a similar way, perhaps this looks like it shouldn't work:

    object o = "";
    
    if(o is string s){
       
    } 
    
    s = "";
    

s looks, to me, like it's created within the scope of the if, yet it's accessible outside the if.. You'll find a similar explanatory transformation if you run that through SharpLab..

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • It doesn't look that way. The source (left) code we see ```k = 1``` and in the transformed code, the only assignment of a literal 1 is ```int num4 =1``` which has parity with the ```int num4 = 0``` (being equivalent to the left side content within ```case 0``` code. In other words, ```k = 1``` is seen implicitly as a variable to be immediately defined and scoped within the ```case 1``` content. In essence, it appears the syntactic sugar is just to define ```k``` to the type implied by the assignment value. At least, that's how I read it. – majixin Feb 25 '22 at 12:41