Q: Compiler compatibility vs. comformance

I got an email from a customer today, in which he noted that the C# compiler allows
you to write:

bool b = …

switch (b)
    case true:

    case false:

despite the fact that the spec does not list bool as one of the types
that you can switch on.

Unfortunately, we’ve shipped the current behavior, and one of our high-order goals
is not to break existing code by changing the compiler. In most cases, that’s a really
good goal, as your customers are justifiably upset when the new compiler breaks their

In this case, however, I think we may be going to far in not fixing a bug because
there’s a chance somebody might have written code that used it. I’m therefore looking
for your opinion (noting, for the record, that it seems that I could sometimes be
replaced by an auto-blogger question-asking piece of software) on what makes the most


How would you have us trade off language conformance (and perhaps language innovation)
vs language stability?

More specifically, when is it acceptable for the compiler to give an error on code
that used to work?


Comments (23)

  1. Eric,

    Personally, I want to see the compiler stick to the language specs, even at the expense of breaking old code. The fact of the matter is that I should not be trying to do something outside of the language specs, and if I am, then I need to accept that I might always be able to do what I am doing. Just like using CreateThread in VB5 and using VarPtr, ObjPtr, and StrPtr in VB5 and VB6. It was my risk to take, if I wanted it.

    Also, I think that you will make better developers out of people. Thinking outside of the box is one thing, breaking the rules is another. When you break the rules, you should be punished.

    I also don’t think that you should give a different compiler warning. The fact of the matter is that Microsoft is going to deliver software that doesn’t conform to the spec sometimes, and if you find a bug, then you fix it (this is really just a bug, just of a different nature). You can’t have the compiler spitting out apologies (which is what this message is tantamount to) because you fixed a bug. At the end of the day, I’d stand by your side if you guys decided to fix bugs rather than support a sloppy product just because some people are using it in the incorrect manner.

    – Nick

  2. Daniel O'Connell says:

    I have to agree with Nicholas on this. Generally, if the spec doesn’t specify it then the compiler shouldn’t allow it(within reason, of course).
    However, there reaches a point where the question is no longer "is the compiler wrong" but "is the spec wrong". In this case I don’t think its something too important, this is really just ifelse syntactical sugar. But in some cases a break from the spec, perhaps, should be looked at as something to consider adding in the next iteration of the language specification instead of blindly removing from the compiler.

    It is not desirable to bind the hands of innovation, but it is to maintain stability and equality across platforms. Does mono allow such a switch statement? Will v3.1 even if v2 does? That kind of thing could be troublesome and removing it unless it is felt to be something that needs to be added to an edition of the language spec seems prudent.

  3. In general I think an issue like this should give a compile warning in vNext, and be an error in v+2. But in this case I wouldn’t mind if you make it an error already in the next version, and conform with the spec.

  4. Kevin Dente says:

    I concur that fixing it is preferable. This is one of the great things about side-by-side deployment of the framework. If your app really depends on out-of-spec behavior of the runtime, it can continue to run But the platform isn’t doomed to support broken behavior for all eternity.

  5. Marco Russo says:

    I agree with other comments: fix compiler conform to specification. But, it would be good a compiler switch (not as a default!) that generate warning and not error for this kind of backward "compatibility". This could be good for people who install the new version of C#, are in a hurry and have to recompile a large set of source code written by someone else. Or, putting it in another way… if in 2006 someone get an old source code (from 2002/2003) and want to recompile, it could be good to have a chance to recompile the program without reinstalling VS.NET 2003… But, I repeat, this should be not the default behaviour, the default should be an error, not a warning.

  6. Keith J. Farmer says:

    Hear hear — please don’t grandfather mistakes!

    But this also just strikes me as just a compiler issue.

    However it’s currently compiled is compatible with the CLI. The only problem I might see would be what the compiled version would decompile to, in C#.

  7. Gerke Geurts says:

    I also prefer sticking to the specification. People are likely to get errors anyway when using other C# compilers (e.g. mono, rotor, etc.). Consistency of should be prime concern, and that is where the language specs define the rules.

  8. Corrado Cavalli says:

    Totally agree with other’s decisions stick with specifications, it could be reported as a warning on next V1 and as an error on next V2.
    What’s importat is to inform devs about this kind of changes (that could break existing code) by providing additional infomation that they cannot ignore (a link near the warning or a "what you should absolutely read about this version" at first startup…

  9. Martin Jul says:

    This kind of problem highlights a deficiency in most programming languages: namely, that the source does not specify which version of the language or compiler it is written for.

    This makes evolving the language harder and leads to all kinds of "source-hell" problems, just when we got rid off the DLL-hell.

    Most protocol designers seem to have acknowledged this and put a version field into the header.

    Of course, this does not solve the problem at hand, but it does take it to another level 🙂

    Plug: I wrote a blog entry on this some time ago on Saturday Sept. 27 2003 – http://mjul.blogspot.com/2003_09_21_mjul_archive.html

  10. chris says:

    Honestly, i’ve seen much worse use of the switch statement; a client that i’ve worked with recently showed me code like this:

    switch (true)
    case (<boolean expression>):


    case (<another boolean expression>):


    as an alternative to a series of if statements. Actually, i was at first interested in the approach in terms of readability, but shyed away in terms of use and future supportability.

  11. Dave says:

    Without commenting on whether the issue should be fixed, I do believe that if something that previously used to work but now no longer does with a newer compiler, it should generate a warning / error.

    However, what I would like to see in these circumstances is a suggestion on an alternative implementation method.

  12. RichB says:

    How about introduce a new attribute like CLSCompliantAttribute? I guess it would be called <ECMACompliant(true)>. This attribute would cause a compile-time warning if switching on a bool was detected.

  13. Chris Jackson says:

    I agree with the preponderance of people that bugs should be fixed, even if it requires a breaking change. However, I really like RichB’s idea, with a slight variation. Make it possible to compile this code, but instead of making compilation the default, give an error message, and allow an attribute to be added that would cause it to go away and become a simple warning. For example, look at BlogX, which you are using. Adding an entry with html worked fine in 1.0, and broke in 1.1. You can fix it by setting validateRequest="false" until you have a chance to rearchitect to not allow the dangerous action or else to confirm that you know it is dangerous and have taken the necessary precautions.

  14. | Anonymous says:

    Maintaining compatibility should not be a black-or-white subject. Compatibility can be maintained with a version switch, this would be beneficial to both parties (Microsoft and any of their customers which may have made use of features/behaviors deemed ‘obsolete’ or ‘incorrect’.

    This could be done with a compiler switch, this would allow Microsoft to continually move forward with development, and always allow developers to flip a switch to buy themselves some time after dicsovering something no longer works.

    personally the out-of-the-box compiler should fit the spec to a sharp T. But we should ALWAYS have a means of getting a ‘compatibility’ build from new compilers, even if we get blasted with warnings.

    On the same note. This isn’t exactly breaking behavior, technically speaking it’s wholly legit code. In my ‘professional’ opinion this behavior should be submitted to the WG. The WG should decide if this should be valid bahavior of the language, because by all accounts it is valid, save for some peice of a document somewhere. Just because nobody had the foresight for something doesn’t mean it’s instantly invalid and undesired behavior, and I’m sure there are people who will go to great lengths to make this an impossibility, but unless such behavior hinders our ability to understand the language or write effective tools using the language, there’s no reason it shouldn’t be part of the language.

    In the end? I think if Microsoft intend to break functionality code such as the above (non-damaging code) should become a warning, not a fatal error, during compile. It should remain a warning forever, that’s Microsoft’s price for making compiler mistakes, it doesn’t cause downtime for their clients and allows them (Microsoft) to focus on moving forward with their own software. At some time in the future the behavior could be obsoleted (after 2 major versions have passed for instance), this would allow companies using obsoleted/deprecated behavior to gear up and conform to the standard.

  15. Mark Levison says:

    I’m a big fan of fixing problems like this. I can live with having to fix a few breaking changes when I upgrade compilers. Further if you have to fix, big api mistakes I can live with that too.

  16. Mark Hurd says:

    chris: Select Case True … Case <Expression> … is a (somewhat) common VBism that provides the same as If .. Else If … but can be more readable some times.

    Because C# is being pushed as based upon published standards, I can see why you might want to break non-conforming code, but it just depends on whether you see all those options available to the Microsoft C/C++ compiler as features or baggage.

  17. Mehran Nikoo says:

    Conforming to the standard (as Microsoft itself has proposed!) has got the priority. If anyone has written and compiled the code using a buggy compiler, they should fix it when csc.exe is fixed. If they are eager to use existing buggy software, they shouldn’t upgrade!

  18. Joe Mayo says:

    Breaking changes that fix bugs to conform with the spec should be okay. However, from a more general perspective, I wouldn’t want compliance with the spec to slow down innovation.

  19. Jeramie Mercker says:

    I agree with the others… If it’s been documented in the spec as working in a particular way, it’s OK to fix a bug that allows other behavior.

  20. DrPizza says:

    It’s always acceptable if it means closer spec conformance.

    One of the things that endlessly annoys me about the C++ compiler is that it doesn’t default to e.g. conformant scoping in for loops.

    A related annoyance is that compiler extensions aren’t individually turnoffandonable. I like non-standard things like unsized last members of arrays and, more importantly, I need them to be able to use Win32 headers. But I don’t want other extensions like binding non-const references to temporaries.

    The compiler should give me fine control over these things. At present it doesn’t. So perhaps have a switch to allow switching on bools (which frankly seems a fair enough to want to do).

    I guess moaning about the C++ compiler in a C#-oriented blog is an exercise in futility, though.

  21. Dnyaneshwar chintamani says:

    please give me the solution for

    What are the reasons of complier linker compatibility of c++ ?