Journal Articles
Browse in : |
All
> Journals
> CVu
> 174
(12)
All > Journal Columns > Francis' Scribbles (29) Any of these categories - All of these categories |
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: Francis' Scribbles
Author: Administrator
Date: 05 August 2005 05:00:00 +01:00 or Fri, 05 August 2005 05:00:00 +01:00
Summary:
Body:
Several very competent programmers have been debating the relative merits of the requirement for a 'Single Entry, Single Exit' coding style. This debate is on comp.lang.c++.moderated. Andrei Alexandrescu's passionate defence of SEME (single entry, multiple exits) has led to the debate being more than just the 'lazy' versus the 'experts'.
You should note that SESE is not just about functions having only one return statement; it is about there being only one exit from any structure.
Part of Andrei's case is that the existence of exceptions in C++ (and C#, Java etc.) means that code often has potential for an alternative exit and the programmer needs to be aware of that and handle it.
Some of you may remember that I have never been an advocate of making SESE an absolute requirement for good code. I also place relatively little value on the arguments from SESE proponents that their code is easier to read. Ease of reading is partly governed by familiarity with the writing style.
Now from my perspective, the primary question is how to get more people writing good code. Here are some thoughts on the topic.
The best is the enemy of good. My observation is that when we present novices with SESE as an absolute, they write very poor code. In a strict sense, their code is SESE compliant but they achieve this with contortions. This bares a similarity to what happens when you tell novice writers that they must not use the passive voice.
There is a wide gap between the excellent programmer and the good one. Adopting methods that make more programmers into good ones without trying to turn them immediately into excellent ones, IMO, is more beneficial in the long term. (Note that I avoided the split infinitive, but did that avoidance help you understand the sentence?)
Now, I freely admit to being less than a devotee of SESE. However, I do have certain personal guidelines:
-
Loops have one exit point. This maybe internal, in which case the loop is written as while(true){ }
-
A loop-iteration may terminate early (for example, with continue) but only once in the body of a loop. Actually I very rarely if ever use continue.
-
All exits from a switch must be to the same place (either all breaks or all returns)
-
If a function contains more than a single return statement, re-view its structure to see if it can be written more cleanly with only a single return.
-
Be wary of negative tests, human beings do not handle these well.
-
Nested structures can usually be replaced by function calls. I make a great deal of use of the unnamed namespace for such functions.
I find application of these guidelines leads to most of my code being single exit, but I think that is a consequence not a target.
The fact that good code usually has single exits points from structures does not, in my opinion, mean that we should teach programmers that SESE is an end in itself. What we should be doing is teaching them coding methods that naturally lead to code that usually has only one exit point.
What I would value, by way of feedback, is more guidelines that help the less experienced programmer write simpler code. So what do you have to offer?
Some time ago, I suggested that we should attempt to produce single topic lists of recommended books. For example, a list of useful books for an experienced C++ (C, Java, C# etc.) or a list for those writing for embedded systems. So far, I have had a single volunteer (to contribute a list for an aspect of Python).
I think we can do much better than that. I think we should do much better than that. Software developers do not have time to waste on reading bad or mediocre books. However, they do not have time to invent everything from scratch. They need good references and tutorials and they need help selecting relevant books.
Like the parable of the Stone Soup, if each contributes a little bit we eventually have something worthwhile. I have neither the expertise nor that time to sit and create lists. Nor do most of you, But each of us has time to draw up a list of books for what we are experts in and then get others to review and refine it.
Consider:
class x; class xyz { public: xyz(); ~xyz(); static int const elements(100); // rest of interface private: x * pointers[elements]; }; xyz::xyz(){ for(int i(0); i != elements; ++i){ pointers[i] = 0; } } xyz::xyz(){ for(int i(0); i != elements; ++i){ delete pointers[i]; } }
Is there a better way to implement the constructor? Of course there is, and I know some of you know it but do you?
Here is a miniscule program. Now I think it is clear what the programmer intended but what do you think a conforming compiler will do with it and why? How should the author have written the definition of p?
struct data { int i; int j; }; int main() { data** p = new (data*)[5]; }
It seems that the writer wants an array of five pointers to data. That looks a little unusual so the first question I would ask is 'Why do you want an array of pointers? Perhaps he is intending to create a two dimensional array of data.
It is easy to answer the immediate question; remove the parentheses surrounding data*.
The reason I asked the question was that I suspected (correctly as it happens) that most (nine out of the eleven) respondents would simply answer the syntax question. That is the easy way to respond to requests for help and many people asking questions like such simple answers, but it does not help them in the end.
By the way, in my opinion, the programmer should either be declaring an array (if the correct size will be fixed and known at compile time) or be using a std::vector<data *>. I am always deeply suspicious of uses of new[] outside low-level classes.
Twice lucky? Thrice lucky? About when China ruled the seas.
Here is Mick Brooks' clue for 1421:
The ultimate answer (read between the lines) is the last Lancastrian's birthday.
By the way, if you have not already come across it 1421 (ISBN 0-553-81522-9) is a fascinating read. I wish I had time to try to untangle wild speculation from the underlying reality. This book should probably be treated as a historical novel. However, like all such novels, it is hard to separate truth from fiction.
Here is another little clue to exercise your grey cells (A knowledge of classic SF might help).
The reverse of this issue adds a score to burning books. (3 digits)
Notes:
More fields may be available via dynamicdata ..