- #71
mXSCNT
- 315
- 1
I don't know fortran, but it sounds like the triple branch is worse than goto. I guess it gets less attention because it's not present in as many languages.
switch (count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while ((count -= 8) > 0);
}
I had forgotten switch case can be used to as means to implement multiple entry points into nested code.D H said:C's (and C++'s) switch statement is essentially a computed goto. This enables constructs such as Duff's device.
Atwood's Coding Horror blog said:The excessive nesting of conditional clauses pushes the code out into an arrow formation:
Code:if if if if do something endif endif endif endif
And you know you're definitely in trouble when the code you're reading is regularly exceeding the right margin on a typical 1280x1024 display. This is the http://c2.com/cgi/wiki?ArrowAntiPattern" in action.
NewsGroup said:From: Linus Torvalds
Subject: Re: any chance of 2.6.0-test*?
Date: Sun, 12 Jan 2003 12:22:26 -0800 (PST)
On Sun, 12 Jan 2003, Rob Wilkens wrote:
>
> However, I have always been taught, and have always believed that
> "goto"s are inherently evil. They are the creators of spaghetti code
No, you've been brainwashed by CS people who thought that Niklaus Wirth
actually knew what he was talking about. He didn't. He doesn't have a
frigging clue.
Wow, that brought back memories. At a previous job, a co-worker doing a code review commented in a email to the group on my use of a single instance of if(...){goto} in a very simple module. The group boss, who would occasionally publicly chastise group members with group emails, responded back with a group email that I should refer to Code Complete, noting he had bought a copy for each member of the group, and that I should follow it's guidelines. In what was a potentially career limiting move I pointed out that, except for the "goto goons", the usage of goto in such cases was acceptable and that the arrow anti-pattern of deep nesting of if else, the one that the group boss himself was pushing, was the only method considered unacceptable by that book. The response after that was that the book was just a general guide.D H said:Steve McConnell, "Code Complete: A Practical Handbook of Software Construction"
if get_resource
if get_resource
if get_resource
if get_resource
do something
free_resource
else
error_path
endif
free_resource
else
error_path
endif
free_resource
else
error_path
endif
free_resource
else
error_path
endif
You may have a point there. Every claimed instance of a "good" goto involves a forward jump, never a backwards jump. Perhaps a goto limited to forward jumps only would not be as risky. Even better might be something like "gonext" which only jumps forward, and only jumps to the nearest following label named "next" (so that you can't interlace two jumps). Something likeAUMathTutor said:Also, jumps [in a switch statement] are only forward jumps.
for(int i=0;i<10;i++)
for(int j=0;j<10;j++){
condition = do_something(i,j);
if(condition == ERR)
gonext;
}
next:
...
smashable{
for(int i=0;i<10;i++)
for(int j=0;j<10;j++){
condition = do_something(i,j);
if(condition == ERR)
smash;
}
}
...
switch(0){
case 0:
condition = do_something();
if(condition == ERR)
break;
condition = something_else();
if(condition == ERR)
break;
...
}
The arrow anti-pattern has the same cyclomatic complexity as the equivalent code rewritten with gotos. The number of "if" statements is probably not the point--maybe there is a way to rewrite the code without so many tests, which would definitely be good if possible, but it's also likely that the conditionals test conditions that have to be tested (irreducibly complicated). That alone doesn't make it an anti-pattern. It's an anti-pattern because the excessive indentation makes it hard to read, and cleanup code may end up far from the resource allocation, as http://c2.com/cgi/wiki?ArrowAntiPattern points out.D H said:The argument against the arrow anti-pattern is that cyclomatic complexity and the presence of software errors are highly correlated. A software item that exhibits this arrow pattern is strongly indicative of that the code is buggy.
do {
// Some code
// Other logical block starts here
// Some code
} while(condition);
// Some code
// Other logical block ends here
top_of_loop:
// Some code
synchronized(resource) {
// Some code
if(condition) { goto top_of_loop; }
// Some code
}
while(true) {
// Some code
synchronized(resource) {
// Some code
if(condition) { continue; }
// Some code
}
break;
}
finished = false;
while(!finished) {
// Some code
synchronized(resource) {
// Some code
if(condition) { continue; }
finished = true;
// Some code
}
}
That's only part of the issue, the main issue is that it the else handling for the outer ifs are farthest away from the code fragment that triggered the else condition. From Code Complete: Moreover, the distance between error-processing code and code that invokes it is too far: the code that sets ErrorState to FileFindError, for example, is 23 lines from the if statement that invokes it.[/quote]AUMathTutor said:It seems like the only argument against the arrow anti-pattern is that it pushes code out to the right when there are more than two nested ifs.
fgotoxyz = FALSE
if(fgotoxyz == FALSE)
{
// step 1
if(step 1 failed)
{
step 1 error handling;
fgotoend = TRUE;
}
}
if(fgotoxyz == FALSE)
{
// step 2
if(step 2 failed)
{
step 2 error handling;
fgotoend = TRUE;
}
}
...
// xyz section starts here
switch(0)
{
case 0:
//step 1
if(step 1 failed)
{
step 1 error handling
break;
}
//step 2
if(step 2 failed)
{
step 2 error handling
break;
}
...
}
mXSCNT said:The arrow anti-pattern has the same cyclomatic complexity as the equivalent code rewritten with gotos.
How do you count the number of "statements required"? Any program could be written in a bounded number of statements, simply by using that bounded number of statements to write an interpreter, then supplying the rest of the program as a string constant argument to the interpreter.For sufficiently large N, there exists an N-statement program written with gotos that requires N! statements when without any gotos.
D H said:That an N statement perniciously written pile of spaghetti might expand to N! statements of neatly written structured program should not be too surprising. This rewriting of the code is essentially the general Boolean satisfiability problem, which is of course an NP-complete problem.