Use of Goto within lexer/parser - c#

I have a lexer/parser pair (which I cribbed off someone else years ago). I am going to be adding a couple of features and thought I would first standardise the use of while(true) containing multiple if/else if/else vs a switch which uses a goto to jump back to before the switch.
(Before the flames start, I don't normally use goto as its evil etc. etc.)
The problem with a while(true) and a nested switch is that the break only breaks out of the switch and cannot get outside the while.
I have done some searching here and seen suggestions to use a return from inside the switch. Whilst this would work in some cases, in others, there is some processing after the while but before returning. Duplicating this code in multiple places doesn't really appeal.
I could also introduce a boolean flag and use that in the while statement to decide whether to break out of the while but that also doesn't appeal as it adds noise to the code.
The current way in the parser of using if/else if/else instead of an inner switch works but I do have a preference for a switch if possible.
The lexer code in general seems to get around this by removing the while(true) and putting a label just before the switch start and using goto to continue the loop. This leaves break meaning stop the loop and, to be honest, seems the cleanest way but does involve the dreadead goto.
Going back to the while(true), I can also see a third way. Use a label after the while(true) and let the switch code use goto to get to it when the loop should end. Break would then mean exit the switch but continue the loop.
So what are the panels views on this? Is goto too abhorrent to use? Or is it OK when there is just a single label to jump to and reduces indenting and produces otherwise clear code? Should parsers/lexers get special license to use gotos?
I can provide some sample code if it would help.

Use of GOTO in disciplined ways is fine. Languages which don't allow breaks out of arbitrarily nested block structures cause this question to be raised repeatedly, since the 1970s when people beat the question of "what control flow structures should a langauge have" to death. (Note: this complaint isn't special to lexers/parsers).
You don't want the scheme with boolean; it just adds extra overhead to the loop checks and clutters the code.
I think you have this problem:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> <want to break out all blocks>
...
}
}
The proper cure with a good language is:
blocks_label:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> exit blocks_label;
...
}
}
if the exit construct exists in your language, that exits
the blocks labelled by the named label. (There's no excuse
for a modern langauge to not have this, but then, I don't
design them).
It is perfectly satisfactory to write, as a poor man's substitute:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> goto exit_these_blocks;
...
}
}
exit_these_blocks: // my language doesn't have decent block exits
On occasion you'll find a language that offers
break <exp>
where exp is usually a constant whole number, meaning, "break out of exp nested blocks". This is an astoundingly stupid idea, as some poor maintainer may later come along an insert another block somewhere in the stack, and now the code does crazy things. (In fact, this exact mistake in a telco switch took out the entire East Coast phone system about 20 years ago). If you see this construct in your langauge, use the poor man's substitute instead.

Within parsers the use of GOTO is perfectly reasonable. When you get down to a base level, the loops and conditions etc are all implemented as gotos, because that is what processors can do - "take the next instruction to be executed from here".
The only problems with gotos, and the reason they are so often demonised, is that they can be an indication of unstructured code, coming form unstructured thinking. Within modern high level languages, there is no need for gotos, because all of the facilities are available to structure code well, and well structured code implies at least some structured thinking.
So use gotos if they are needed. Don't use them just because you can't be bothered to think things through properly.

Related

Is it possible to always eliminate goto's?

While making everthing with goto's is easy (as evidenced by f.ex. IL), I was wondering if it is also possible to eliminate all goto statements with higher level expressions and statements - say - using everything that's supported in Java.
Or if you like: what I'm looking for is 'rewrite rules' that will always work, regardless of the way the goto is created.
It's mostly intended as a theoretical question, purely as interest; not as a good/bad practices.
The obvious solution that I've thought about is to use something like this:
while (true)
{
switch (state) {
case [label]: // here's where all your goto's will be
state = [label];
continue;
default:
// here's the rest of the program.
}
}
While this will probably work and does fits my 'formal' question, I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
So, is there a better solution?
Update 1
Since a lot of people seem to think the question is 'too broad', I'm going to elaborate a bit more... the reason I mentioned Java is because Java doesn't have a 'goto' statement. As one of my hobby projects, I was attempting to transform C# code into Java, which is proving to be quite challenging (partly because of this limitation in Java).
That got me thinking. If you have f.ex. the implementation of the 'remove' method in Open addressing (see: http://en.wikipedia.org/wiki/Open_addressing - note 1), it's quite convenient to have the 'goto' in the exceptional case, although in this particular case you could rewrite it by introducing a 'state' variable. Note that this is just one example, I've implemented code generators for continuations, which produce tons and tons of goto's when you're attempting to decompile them.
I'm also not sure if rewriting in this matter will always eliminate the 'goto' statement and if it is allowed in every case. While I'm not looking for a formal 'proof', some evidence that elimination is possible in this matter would be great.
So about the 'broadness', I challenge all the people that think there are 'too many answers' or 'many ways to rewrite a goto' to provide an algorithm or an approach to rewriting the general case please, since the only answer I found so far is the one I've posted.
This 1994 paper: Taming Control Flow: A Structured Approach to Eliminating Goto
Statements proposes an algorithm to eradicate all goto statements in a C program. The method is applicable to any program written in C# or any language that uses common constructs like if/switch/loop/break/continue (AFAIK, but I don't see why it wouldn't).
It begins with the two simplest transformations:
Case 1
Stuff1();
if (cond) goto Label;
Stuff2();
Label:
Stuff3();
becomes:
Stuff1();
if (!cond)
{
Stuff2();
}
Stuff3();
Case 2
Stuff1();
Label:
Stuff2();
Stuff3();
if (cond) goto Label;
becomes:
Stuff1();
do
{
Stuff2();
Stuff3();
} while (cond);
and builds on that to examine each complex case and apply iterative transformations that lead to those trivial cases. It then rounds off with the ultimate gotos/labels eradication algorithm.
This is a very interesting read.
UPDATE: Some other interesting papers on the subject (not easy to get your hands on, so I copy direct links here for reference):
A Formal Basis for Removing Goto Statements
A Goto-Elimination Method And Its Implementation For The McCat C Compiler
A situation where a goto can be avoided, but I think it is better to use it:
When I need to exit a inner loop and the loop:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
for(int j = 0; j < inner.Count; j++)
{
// Some code.
if (condition) goto Finished;
}
}
Finished:
// Some more code.
To avoid the goto you should do something like this:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
bool conditon = false;
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) break;
}
if (condition) break;
}
// Some more code.
I think it looks much nicer with the goto statement.
The second situation is okay if the inner loop was in a different method.
void OuterLoop(list)
{
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
if (InnerLoop(inner)) break;
}
}
bool InnerLoop(inner)
{
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) return true;
}
return false;
}
I have some practical experience of attempting to take an unstructured program (in COBOL, no less) and render it as structured by removing every instance of GOTO. The original programmer was a reformed Assembly programmer, and though he may have known about the PERFORM statement, he didn't use it. It was GOTO GOTO GOTO. And it was serious spaghetti code -- several hundred lines worth of spaghetti code. I spent a couple of weeks worth of spare time trying to rewrite this monstrous construct, and eventually I had to give up. It was a huge steaming pile of insanity. It worked, though! Its job was to parse user instructions sent in to the mainframe in a textual format, and it did it well.
So, NO, it is not always to possible to completely eliminate GOTO -- if you are using manual methods. This is an edge case, however -- existing code that was written by a man with an apparently twisted programming mind. In modern times, there are tools available which can solve formerly intractable structural problems.
Since that day I have coded in Modula-2, C, Revelation Basic, three flavors of VB, and C# and have never found a situation that required or even suggested GOTO as a solution. For the original BASIC, however, GOTO was unavoidable.
Since you said it's a theoretical question, here is the theoretical answer.
Java is Turing complete so of course, yes. You can express any C# program in Java. You can also express it in Minecraft Redstone or Minesweeper. Compared to these alternatives expressing it in Java should be easy.
An obviously more practical answer though, namely an intelligible algorithm to do the transformation, has been given by Patrice.
I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
That's what you're always going to get when looking for a general pattern which can replace any use of goto, something which does exactly the same as a goto would do. What else could it be? Different uses of goto should be replaced with best matching language construct. That's why constructs as switch statements and for loops exist in the first place, to make it easier and less error prone to create such a program flow. The compiler will still generate goto's (or jumps), but it will do so consistently where we will screw up. On top of that we don't have to read what the compiler generates, but we get to read (and write) something that's easier to understand.
You'll find that most compiler constructs exist to generalize a specific use of goto, those constructs where create based on the common patterns of goto usage which existed before it. The paper Patrice Gahide mentions sort of shows that process in reverse. If you are finding goto's in your code you are either looking at one of those patterns, in which case you should replace it with the matching language construct. Or you are looking at essentially unstructured code in which case you should actually structure the code (or leave it alone). Changing it to something unstructured but without goto can only make matters worse. (The same generalization process is still going on by the way, consider how foreach is being added to compilers to generalize a very common usage of for...)

Why not GOTO Statement? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am doing Masters in Software Engineering. From College to University i heard from my teachers and instructors that never use GOTO statement in Programming Language.According to
Software Engineering By D. Sundar
USE of goto statements makes a program unstructured and makes it very
difficult to understand.
and i also read the same in book by MICROSOFT on its first page that never use GOTO Statmement in Programming.
It always arises question in my mind that if we are instructed that never use GOTO Statement then why it is the part of many common programming languages ?
At least for some programming languages (none of which I'm the designer of, obviously) like C and C++, I imagine it's there because it
Closely models what the hardware really can do, which is kind of the goal in these languages.
Is sometimes actually useful and better than more "structured" approaches.
The most common example of when goto is often considered good is when doing nested error/resource management in C. See for instance the Linux kernel, a fairly large and successful C project which uses goto for this purpose.
You want to read the seminal "Go to statement considered harmful" by Edsger W. Dijkstra (1968!)
There is no goto statement in java. The Java keyword list specifies the goto keyword, but it is marked as "not used".
You instructed not to use goto because they want to teach you how to write code.
but sometimes goto can be useful.
when you want to break at once from a multi-level loop. you can add an exit condition to each step. and you can use goto endloop
look at this example: (psaudo code)
while(cond1){
while(cond2){
while(cond3){
if(want to break){
goto endloop
}
do something
if(want to break2){
goto endloop
}
}
do something
}
do something
}
endloop:
do something else
without the goto it may look like this:
while(cond1 && exitloopflag){
while(cond2 && exitloopflag){
while(cond3 && exitloopflag){
if(want to break){
exitloopflag = true;
break;
}
do something
if(want to break2){
exitloopflag = true;
break;
}
}
if(exitloopflag)
break;
do something
}
if(exitloopflag)
break;
do something
}
do something else
so we can argue which code readability is better...
The presence of goto in any modern programming language is largely vestigial, sort of like the human appendix. Its functionality has been replaced with conditional and looping control structures (if-then-else, for/while/loops, switch/case statements, etc.). It hangs around in languages like C and C++ because there are edge cases where it's still quite useful, such as breaking out of a deeply nested loop:
for (...)
{
for (...)
{
for(...)
{
...
// hit a fatal error, need to break out to outermost scope
goto whoopsiedoodle;
}
}
}
whoopsiedoodle:
...
However, its use is discouraged for a number of very good reasons: since it can branch either direction in a function, it can destroy the ability to debug code by simple inspection. For example, given the following snippet:
i = 1;
label: printf("i = %d\n", i);
What value gets printed for i? How many times will that print statement be executed? Until you account for every instance of goto label;, you can't know. Now, imagine the code is structured something like the following:
i = 0;
goto label;
foo: ...
...
i = 1;
label: printf("i = %d\n", i);
...
goto foo;
...
Now, imagine several dozen (or even several hundred) lines of code for each ... in the snippet above. Also imagine the presence of 10 or 11 other labels scattered throughout, with associated goto statements scattered largely at random. This is modeled after some real-world code I encountered early in my career. The only way to debug code like this is to trace the execution, line by line, accounting for every goto along the way. This code was badly written to begin with (a monolithic, 5000-line main function, literally hundreds of separate variables, some declared at file scope, some local to main, and other atrocities), but the use of goto was a force amplifier that turned merely bad code into an unmaintainable sludge. This code defined "brittle"; we literally could not change a single line of it without breaking something else.
Excessive use of goto can also hinder the compiler's ability to optimize code. Modern compilers are quite smart, and can take advantage of structured programming techniques to do effective branch prediction or unroll loops for real performance gains. Code like the above is almost impossible for the compiler to optimize. That real world code that the above snippet is modeled on? We tried to compile it with optimization flags turned on (gcc -O1). The compiler ate all available RAM, then it ate all available swap, causing a kernel panic.
We told the customer they would either need to buy faster hardware, or allow us to rewrite the entire thing from the keel up. They wound up buying faster hardware.
goto can be used effectively, as long as you obey the following rules:
Branch forward only.
Never branch into the body of a control structure (i.e., don't bypass the if, for, while, or switch condition).
Avoid branching over large sections of code.
Id like to give an explanation, why you should use GOTO very carefully.
I do not say GOTO is a bad statement at all, that is one of the reasons, why it is still implemented in C++ (and due to compatibility reasons to C), in JAVA its only reserved as a keyowrd.
I can show you examples where GOTO is the best solution (in my point of view)
But you should prevent using it due to the following reason:
(Taken, translated and modified by me, from the Book Ohne C Zu C++)
Imagine you play a game like Settlers of Catan, wherever you go, anyone has its own
rules.
That is ok, you just need to learn the rules and then you can play with them.
But what is if they will not teach u there rules, and just use it? you will loose the fun in gaming with
them very fast.
A goto statement is like a new Settler of Catan rule.
Programming is hard enough to understand when you can reliably assume that you start at >the top, execute 1 line at a time, going down, one line at a time.
Using a goto statement throws that assumption out the window, and all of the sudden, the "game! is uncertain. It's a new and uncertain rule.
In some languages, it is used for exception handling (e.g. VBA)
Java has goto as a keyword but it is doing nothing. I belivie they did this, that you can't name anything goto
However, in some cases goto can be useful!
goto is explicitly not allowed in Java. It is there in other languages because it is easy to implement as it is a simple instruction in machine code, not because it is a good idea.
BTW You can do something like a goto in Java. See if you can easily work out what this simple example does, and if you can't you are answering your own question. If it's obvious to you what this does and how it works, you have to consider than many would find this confusing.
FOUND: {
for(String s: list)
if(s.contains(like))
break FOUND;
System.out.println(like + " not found");
}
Goto statements model machine code; there are very limited flow-control constructs in machine code, and there is no way to write a significant machine code program without the equivalent of a goto.
The original high-level languages, such as COBOL and FORTRAN, had Gotos because that's how people knew to control their flow from doing machine code on their machines. The C language was also created with one, though years later, partially because that language was specifically created to be easy to compile to efficient machine code -- some of the C language constructs, such as the increment/decrement operators, are there because the machine for which C was originally created had those sub-operations in its machine code. It can be said that C is not a high-level language, it is a structured assembler (and there's nothing wrong with that, it was ahead of its time, and still highly useful).
What Dijkstra and others figured out, though, is that (1) it isn't necessary to have a goto if you have sufficient higher-level constructs for flow control, and (2) it is horribly error-prone. I remember reading that there were analyses of code that found that a goto statement was 9 times more likely to be in error than any other kind of statement.
It is ironic because it is not the least difficult to understand conceptually what the statement is doing; it's just that the uses programmers make of it too often turn out to make the program overall harder to understand.
Goto is permitted when we're jumping
out of a scope,
just next behind the scope close.
All other cases are invalid (jumping into a cycle, jumping into the middle of an if-block, jumping into another function, OMG, happy Halloween).
As there are several way to break a scope, like break, break label, return etc, there is no situation where pure goto must be used (except some early languages which does not support some of above, usually break label).
Other words, goto has not disappeared (it's impossible to write a program without changing the order of execution), we just make distinctions by using different keywords for different types of execution path. Goto now has special cases, which have own keywords. It also makes code easier to understand.

Does anyone still use [goto] in C# and if so why? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I was wondering whether anyone still uses the "goto" keyword syntax in C# and what possible reasons there are for doing so.
I tend to view any statements that cause the reader to jump around the code as bad practice but wondered whether there were any credible scenarios for using such a syntax?
Goto Keyword Definition
There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:
A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.
The goto statement is also useful to get out of deeply nested loops.
Here's an example for the latter one:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.
I remember this part
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
To something like this
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Refer This
I use it extensively in Eduasync to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.
In "normal" code though, I can't remember the last time I used it...
The compiler uses goto statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return keyword - I'm pretty sure that the generated XML serialisation types also have a few goto statements in there somewhere too.
See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.
Other than generated code there isn't a good reason to use a goto statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.
See Go-to statement considered harmful for an argument against goto as well as a classic piece of programming history.
I don't remember ever using goto. But maybe it improves the intent of a forever loop that you really never want to exit (no break, but you can still return or throw):
forever: {
// ...
goto forever;
}
Then again, a simple while (true) should suffice...
Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.
goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.
The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.
One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.
I should avoid the use of break but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break it is time to refactor.
If anybody can propose a use of goto that seems better than refactoring I will gladly withdraw my answer.
I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.
Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.

Why do you need to put break after the last label of a switch statement?

Surely the compiler knows that it's the last label of the switch statement?
Having a break after your switch's final case statement is good defensive programming. If, perhaps in the future, another case statement is added below, it removes the risk of the program's flow falling through from the case above.
It's because in C++ this is what happens:
switch(a)
{
case 1:
// do stuff
case 2:
// do other stuff
}
If a is 1, then - according to C++ rules - both "do stuff" and "do other stuff" would happen. So that C++ programmers coming to C# do not get tripped up (and to make code clearer all 'round), C# requires that you explicitly specify whether you want to break or fall through to a different label.
Now, as for why you need the break on the last block, that's a simple matter of consistency. It also make re factoring easier: if you move the cases around, you don't suddenly end up with errors because of a missing break statement. Also, what happens when you want to add another label, etc, etc.
Consistency. Same reason as being able to have a comma after the last enum definition or the last assignment in an object instantiation statement with braces. And the last case might not always be the last case.
It also makes it so there are fewer special cases.
And if that's the case, then it is easier to learn, write, or read. Although that adds to the consistency thing.
In C# switch statements you must explicitly state to break or goto another case or goto default.
In C and C++, switch statements have fall through labels without a break. Having the user explicitly say what they want to do is important in C# to avoid bugs. A lot of users come to C# from C++ for example.
About the last case statement in particular that you're asking about. I can think of 3 good reasons.
It's important to keep things consistent in any language.
What if you append another case after it later on, what should be done with default?
Why should break be the default? Why not goto? There is ambiguity here.
According to http://msdn.microsoft.com/en-us/library/06tc147t.aspx
You cannot "fall through" any switch section, including the last one.
Fall through can be avoided by any of the following: break, goto, or return.
Actually There is one case when you don't have to put break
Consider this code:
using System;
public class Program
{
public static void DoStuff()
{
}
public static void DoAnotherStuff()
{
}
public static void Main()
{
switch(1)
{
case 1: DoStuff(); break;
default: DoAnotherStuff();
}
}
}
Using C# 4.0 compiler it only gives you a nice CS0162: Unreachable code warning
It appears that since switch has a constant expression the compiler already knows wich path it's going to execute, then just ignores the dafault label.
The cool thing is that if you change switch(1) to switch(2) it no longer compiles because the default label lacks its break.
Edit: From the C# Reference
The requirement in C# is that the end of every switch section, including the final one, is unreachable. Although this requirement usually is met by using a jump statement, the following case also is valid, because the end of the statement list cannot be reached.
case 4:
while (true)
Console.WriteLine("Endless looping. . . .");
That explains why the default does not need a break. In fact any unreacheable label doesn't need a break nor return nor goto
When using a switch, to break is not the only option. You also have the option of going to another case, going to the default case, going to another label, or returning. It is also possible to have multiple cases that have a single implementation body. Since there are up to five options plus the ability to have multiple cases for one implementation, the compiler is not able to simply put in the "correct" answer.
You have to choose what you intend to do. It ensures the compiler does the right thing, makes your code clearer, and makes it more difficult to do dumb-programmer-things, like add another case after the "last one", and forget to put in a break/goto/return.
According to this blog post by Eric Lippert (Case 2), it allows you to be able to arbitrarily re-order your switch sections without accidentally introducing a breaking change:
It [the compiler] requires that every switch section,
including the last one, have an
unreachable end point. The purpose of
this rule, and of the no-fall-through
rule in general, is that we want you
to be able to arbitrarily re-order
your switch sections without
accidentally introducing a breaking
change.
As mentioned, you can use default:, but consider case null too. case null: does need a break;
case null:
iEvaluatedToNothing();
break;
If you want to "waterfall" down you can do something like this;
switch (deliverMail)
{
case null:
case "":
case "Address0":
deliverMail0();
goto case "1";
case "1":
deliverMail1();
break;
}
You can use this with breaks as needed, but one is required on the last evaluation.

Nested or not nested if-blocks?

I was wondering if there is a performance difference when using ifs in C#, and they are nested or not. Here's an example:
if(hello == true) {
if(index == 34) {
DoSomething();
}
}
Is this faster or slower than this:
if(hello == true && index == 34) {
DoSomething();
}
Any ideas?
Probably the compiler is smart enough to generate the same, or very similar code, for both versions. Unless performance is really a critical factor for your application, I would automatically choose the second version, for the sake of code readability.
Even better would be
if(SomethingShouldBeDone()) {
DoSomething();
}
...meanwhile in another part of the city...
private bool SomethingShouldBeDone()
{
return this.hello == true && this.index == 34;
}
In 99% of real-life situations this will have little or no performance impact, and provided you name things meaningfully it will be much easier to read, understand and (therefore) maintain.
Use whichever is most readable and still correct (sometimes juggling around boolean expressions will get you different behavior - especially if short-circuiting is involved). The execution time will be the same (or too close to matter).
Just for the record, sometimes I find nesting to be more readable (if the expression turns out to be too long or to have too many components) and sometimes I find it to be less readable (as in your short example).
Any modern compiler, and by that I mean anything built in the past 20 years, will compile these to the same code.
As to which you should use then it depends whichever is more readable and logical in the context of the project). Generally I would go for the second myself, but that would vary.
A strong point worth consideration though arises from maintenance. One of the more common bugs I have hunted down is a dangling if/else in the middle of a block of nested ifs. This arises if you have a complex series of if else conditions which has been amended by different programmers over a period - often several years. For example using pseudo-code for a simple case:
IF condition_a
IF condition_b
Do something
ELSE
Do something
END IF
ELSE
IF condition_b
Do something
END IF
END IF
you'll notice for the combination !condition_a && !condition_b the code will fall through the conditions doing nothing. This is quite easy to spot for just the pair of conditions, but can get very easy to miss very quickly once you have 3, 4 or more if/else conditions to check. What commonly happens is the nested structure is correct when first coded, but becomes incorrect (in terms of the business outputs) at some later point because the maintenance programmers will not understand or allow for the full range of options.
It's therefore generally more robust, over time, to code using combined conditions in the if structure adopting the flatest feasible structure and keep nesting to a minimum, hence with your example as there's no logical reason not to combine the two conditions into a single statement then you should do so
I can't see that there will be any great performance difference with either, but I do think that option two is MUCH more readable.
I don't believe there is any performance difference you might be experiencing between the two implementation..
Anyway, I go for for the latter implementation because it is more readable.
Depends on the compiler. The difference will be more apparent when you have code after the close of the nested if, but before the close of the outer.
I've wondered about this often myself. However, it seems there really is no difference (or not much to speak of) between the options. Readability-wise, the second option is more readable and so I usually choose that one unless I anticipate having to code specifically for each condition for some reason.

Categories