Case statement does not handle all possible cases lazarus / 64-FPC development ---------------------------------------------------------------------- Zoran · 2021-06-19 16:54 When compiling my programs with FPC from trunk, the compiler gives a lot of warnings: QuoteWarning: Case statement does not handle all possible cases Isn't it quite normal programming practice, to do something in some cases, without covering all possible values from some enumeration? Why should a programmer be warned to cover all possible cases? ---------------------------------------------------------------------- Kays · 2021-06-19 17:08 Quote from: Zoran on June 19, 2021, 06:54:22 pmWhy should a programmer be warned to cover all possible cases?It is an ISO requirement. ISO 7185, § 6.8.3.5 “Case-statements”QuoteOne of the case-constants shall be equal to the value of the case-index upon entry to the case- statement; otherwise, it shall be an errorNow an “error” is aQuoteviolation by a program of the requirements of the requirements to this International Standard that a processor is permitted to leave undetected.In other words, an “error” may produce just a warning as the FPC [trunk version] does now. This becomes more apparent by the wording of ISO 10206 (“Extended Pascal”), § 6.9.3.5 “Case-statements”, which says “dynamic violation” (cf. § 3.1). Quote from: Zoran on June 19, 2021, 06:54:22 pmIsn't it quite normal programming practice, to do something in some cases, without covering all possible values from some enumeration?I think it was TP that introduced the else-clause and the possibility of a fall- through/bypassed case-statement. For Delphi-compatibility the FPC adopted this malpractice. Pascal is very well designed and there are reasons why all possible case-labels have to appear in case- statements. ---------------------------------------------------------------------- winni · 2021-06-19 17:13 Quote from: Kays on June 19, 2021, 07:08:37 pmI think it was TP that introduced the else-clause and the possibility of a fall- through/bypassed case-statement. For Delphi-compatibility the FPC adopted this malpractice. Pascal is very well designed and there are reasons why all possible case-labels have to appear in case- statements. Hi! TP did not invent the else-clause for the case statement. The misstreated it. The original syntax for Pascal is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Case i of1: .....;2: ....;otherwise ....:end; fpc knows the original syntax. Winni ---------------------------------------------------------------------- Zoran · 2021-06-19 17:23 Thank you, Kays. However, for decades, FPC, Delphi and TP programmers have been very used to case statements without covering all possible values. Perhaps the warning should be issued in iso mode only? ---------------------------------------------------------------------- Bart · 2021-06-19 19:57 If it bothers you filter it out using the appropriate -vmxxxx in your fpc.cfg? E.g. I have this in my fpc.cfg Code: [Select]#Don't show the "function X; marked as inline is not inlined" warning -vm6058Because I don't bother. Bart ---------------------------------------------------------------------- MarkMLl · 2021-06-19 20:45 Quote from: Zoran on June 19, 2021, 07:23:00 pm Thank you, Kays. However, for decades, FPC, Delphi and TP programmers have been very used to case statements without covering all possible values. Perhaps the warning should be issued in iso mode only? "I hear what you're saying", but as a refugee from Modula-2 I'm entirely happy with ensuring that every case has an otherwise clause irrespective of whether the selector is a small enumeration or a larger arbitrary integer or cardinal type. My own feeling is that coverage should be complete if the selector is an enumeration, but that it might arguably be relaxed if it is a numeric type. In practice that distinction might not be easy or desirable to make, in which case a compiler should err on the side of caution. MarkMLl ---------------------------------------------------------------------- nanobit · 2021-06-20 01:45 Quote from: Kays on June 19, 2021, 07:08:37 pmI think it was TP that introduced the else-clause and the possibility of a fall- through/bypassed case-statement. For Delphi-compatibility the FPC adopted this malpractice. Pascal is very well designed and there are reasons why all possible case-labels have to appear in case- statements. For exactness it should be noted here that "else" in FPC has a different meaning than "else" in Delphi, C++, C#. The latter languages implement "all other values of underlying type", FPC implements only "all other defined values". https://bugs.freepascal.org/view.php?id=36983 ---------------------------------------------------------------------- speter · 2021-06-20 02:02 The discussion above prompted me to look at my old pascal code. I found (to my surprise) that Microsoft's Pascal compilers used else...otherwise (I used v3.13, v3.31 & v4). I had totally forgotten about using "otherwise" with Microsoft's compilers. I also found a program I wrote in 1989 to convert my 'old' pascal code to the Turbo Pascal dialect; that included substituting "else" for "otherwise". cheers S. ---------------------------------------------------------------------- PascalDragon · 2021-06-20 09:50 Quote from: Zoran on June 19, 2021, 07:23:00 pmHowever, for decades, FPC, Delphi and TP programmers have been very used to case statements without covering all possible values. Perhaps the warning should be issued in iso mode only? No, because enumerations type in FPC do behave differently from those in Delphi and TP and they already did so before the warning thus potentially leading to bugs for people. Which was why the warning was introduced (and not because ISO required it, though there it's of course welcome as well). As nanobit mentioned, if you have an enum with holes then only those values that are indeed defined are considered valid, thus it is valid for the compiler to exploit this behavior for optimizations which might lead to unexpected results for the developer if they didn't adhere to the warning. ---------------------------------------------------------------------- Jonas Maebe · 2021-06-20 10:14 Quote from: PascalDragon on June 20, 2021, 11:50:26 amAs nanobit mentioned, if you have an enum with holes then only those values that are indeed defined are considered valid, thus it is valid for the compiler to exploit this behavior for optimizations which might lead to unexpected results for the developer if they didn't adhere to the warning. No, the values within "holes" are defined. It's values < low(enumtype) or > high(enumtype) that are undefined. It's also not just for "case", but for any expression. E.g. the compiler will also optimise away comparisons like "if enumval < low(enumtype) then ..." (with a warning about unreachable code), and will never insert range checks for "arr[enumval]" in case "arr" is defined as an "array[enumtype]". Delphi does the same for array indexing for some reason, even though for the rest it indeed generally handles enums like C rather than like Pascal. Also, in ISO modes this warning is in fact an error. ---------------------------------------------------------------------- nanobit · 2021-06-20 11:20 Jonas, I added a note about why we can improve the case-statement regardless of other expressions. https://bugs.freepascal.org/view.php?id=36983 ---------------------------------------------------------------------- Jonas Maebe · 2021-06-20 11:32 Programming languages are based on consistency. All statements must abide by the same rules regarding a particular type, otherwise you have to program with the language reference manual next to you so you can look up for each expression/statement how it bahaves. Either an enum is either only defined between min and max (ISO Pascal, FPC, Java), or it's defined as long as it fits in the underlying type (C, C++, C#). Delphi is buggy in this regard: it treats array accesses like FPC and the rest like C/C++/C#. ---------------------------------------------------------------------- nanobit · 2021-06-20 12:10 Ok, then we disagree about this. I agree with you on the definedness (min, max), but not the conclusions about how to handle the undefined values. ---------------------------------------------------------------------- Jonas Maebe · 2021-06-20 12:21 "Undefined" literally means that the compiler does not and cannot guarantee any particular kind of handling. To have that, you have to make such behaviour defined (like C and C++ do).