4 ms·
> The Apple bug is just a concrete example of how a different language design decision (requiring braces) could have avoided this particular bug. I don't see h
by brianberns 13y ago
> The Apple bug is just a concrete example of how a different language design decision (requiring braces) could have avoided this particular bug.
I don't see how requiring braces would have necessarily avoided the Apple bug. Whoever was responsible for creating the extra "goto fail" might still have left it outside the scope of an if-statement.
if (error_of_first_kind)
{ goto fail; }
if (error_of_second_kind)
{ goto fail; }
if (error_of_third_kind)
{ goto fail; }
if (error_of_fourth_kind)
{ goto fail; }
if (error_of_fifth_kind)
{ goto fail; }
{ goto fail; }
if (error_of_sixth_kind)
{ goto fail; }
The_truly_important_code_handling_non_erroneous_case
It all depends on how the extra line got there in the first place. Presumably there was a mistake made while editing the file. Braces don't necessarily eliminate those kinds of problems.
- DatBear 13y agoWho on earth would ever format code like that?
- SoftwareMaven 13y agoAssuming this is "C with required conditional braces", this would exhibit the same behavior as the original bug. Introducing a new scope with {} is valid (and regularly used) C. The problem here is that, visually, this class of error doesn't stand out, because, when you scan the code, it just looks ok (albeit, ever so slightly less right in your example). And that brings us back to language design. It's hard to have this type of bug and not bring up Python as an example, because Python behaves as your eye processes it. if error_of_fifth_kind: goto fail goto fail Those two gotos are in the same block, because they are indented the same. People continue to freak out over significant spacing, but there is a lot of value in it.
- pdw 13y agoMeyer argues that a language shouldn't have a separate block statement. Instead block structure should be integrated in the control flow statements. That would result in this code: (I'm keeping your indentation style) if error_of_fifth_kind then goto fail end then goto fail end Which is simply a syntax error.
- brianberns 13y agoInteresting. This works because there's no explicit "begin" to go with the "end". I would normally consider this kind of asymmetry to be a language design flaw, but I suppose it does address this particular problem. Of course, I think you could still end up with this pretty easily: if error_of_fifth_kind then goto fail end goto fail if error of sixth_kind then goto fail end
- pdw 13y agoWell, Meyer doesn't let any chance to bash C/C++ go unused :) But a good syntax should minimize the chance that an accidental insertion/transposition/deletion of a character/word/line results in a valid program. [A dramatic example of bad syntax comes from a FORTRAN, where a loop between the current line and the line with label 10 looks like this: DO 10 I=1,100 and this code: DO 10 I=1.100 declares a variable named "DO10I". Hopefully your compiler will warn that label 10 is unused.]
- wernercd 13y agoOr similarly: if error_5 { goto fail; } /* line deleted here */ goto fail; } if error_7 { goto fail; } Many ways to skin the same cat, but it boils down to following good practices that emphasize errors like this (presumably removing an error condition and leaving the goto).
- usefulcat 13y agoAh, a fair point! However, since we're talking about the hypothetical language what-C-might-have-been, I would suggest a further improvement: require braces for all conditionals /and/ require that the opening and closing braces shall not be on the same line.
- byuu 13y agoThat would really start to hurt readability. There are plenty of instances where the body is very similar save for a small change, and having it lined up in a grid makes it much easier to read. As a contrived example, you can look straight down to see the action values here: if(condition_1) { action(318); } if(condition_2) { action(219); } if(condition_3) { action(142); } In my opinion, the bigger risk is having a single-statement if have its payload on the next line. if(x.open()) x.close(); //very difficult to add another statement accidentally here if(x.open()) x.close(); //much easier to do so here But of course I wouldn't want to start treating whitespace as special in C.
- brianberns 13y agoAdding semantics to white space would be a huge change to the design of C (and most other languages).
- talideon 13y agoCongratulations! You've constructed a strawman argument. Sure, if somebody used a brace formatting rule like the one you've given, which is explicitly done in a way that wouldn't have avoided the issue, it still would've happened. However if somebody was to consistently place the statements on a line of their own as just about any real world brace formatting rule would, the issue would be avoided. Thus: if (error_of_first_kind) { goto fail; } /* ... */ if (error_of_fifth_kind) { goto fail; goto fail; } if (error_of_sixth_kind) { goto fail; } The_truly_important_code_handling_non_erroneous_case Is safe, as would be: if (error) { goto fail; } if (error) { goto fail; } Or: if (error) { goto fail; } The idea behind always using braces is to _avoid insertion errors_ when editing. If you need to jiggle the braces around to go from one statement more than one, you're doing it wrong.