C++: Short question regarding switch and break - c++

Example:
switch( x )
{
case y:
if ( true )
{
break;
}
cout << "Oops";
break;
}
If the switch statement selects y, will Oops be written to the standard output?
- Is break in switch statements a dynamic keyword like continue which can be called under conditions or static like a closing bracket }?

break breaks out of an enclosing switch, while, for, or do ... while. It doesn't break out of an enclosing if or bare block. Pretty much exactly like continue.
It's certainly not part of the required syntax of a switch statement (like a close-brace is part of the syntax of blocks). break is a statement, essentially meaning "transfer execution to the point after the end of the innermost breakable construct".

No, Oops will not written out, the break jumps behind this statement.
You can use break statements conditionally just fine, you only have to watch out when you create nested statements that also support break (i.e. loops).

break is absolutely dynamic. So, if you write if (false) break; your Oops would be written out.

Think of break in this case as a goto end_of_switch.

No, it will not be printed in your case. break only breaks from switches and loops, not conditionals or functions or arbitrary enclosing scopes. Therefore, a more relevant question would be whether Oops is printed in this case:
switch( x )
{
case y:
for ( int i = 0; i < 10; ++i )
{
break;
}
cout << "Oops";
break;
}
And the answer here is yes, it will. The break will break out of the for, not the switch.

No. It would break out of the switch construct. "break" is used to come out of the innermost loop construct or switch construct. So, in your case the "oops" is not printed out on the screen. If you want that to happen, in your code, you could use if(false) instead of if(true).

Related

Bug in c++ program during a simple loop

I'm trying to solve this problem as few lines of code as possible.
problem statement:
someone managed to say hello if several letters can be deleted from the typed word so that it resulted in the word "hello"... I'm testing if he could or not
#include <iostream>
int main() {
char c;
int i=0;
while(i!=5 && (cin>>c) && c!='\n'){
if(c=="hello"[i])
i++;
}
cout<<((i==5)?"YES":"NO");
}
There's a bug when it should print "NO". The program waits for more input. I think the loop doesn't finish until i==5 but it never finishes when c=='\n'.
Before you pack your program to minimize the LOC (and I assume that you have a really good reason to care about this because otherwise it is a foolish thing to do) make it right!
Try putting the i != 5 test BEFORE the cin >>c test. Otherwise you read one extra character when you do get a "hello"
Edit: Just to be clear, the code in the question has now been modified to incorporate this suggestion.
You have a while loop there
while(i!=5 && (cin>>c) && c!='\n')
{ ... }
...which you can rewrite for easier debugging. In general, instead of any loop...
while (X)
{ Y }
...you can also write...
while (true)
{
if (!X) break;
Y
}
For your loop, that would be this code:
while (true)
{
if (!(i!=5 && (cin>>c) && c!='\n'))
break;
...
}
Now, I assume you are aware of the short circuit evaluation of the logical AND operator. If not, search the web for that term! With that knowledge, you can rewrite your loop like this:
while (true)
{
if (!(i!=5))
break;
if (!(cin>>c))
break;
if (!(c!='\n'))
break;
...
}
Of course, you can still simplify a few double negations there, but the idea should be clear. This change now allows you to e.g. step through this in a debugger to evaluate each loop exit condition separately. This is important, because the second loop condition also has side effects! In addition, you could e.g. add some debug output that tells you the reason why the loop was exited. Further, for the check that has side effects, you can inspect the intermediate state (or output the state, if you prefer that way), which will give you further insight on the issue.
Lastly, all >> operators on istreams by default skip whitespace, which includes spaces, tabs and newlines, so your last check will never cause the loop to exit. You can tell the stream to not skip whitespace though, if that's what you want. How to do that should be really simple to find out using another websearch. ;)

Convincing a colleague about their if not being nested

One of my university colleagues, who has started programming this year, sometimes writes if statements like this:
if(something) doA();
else
if(something2) doC();
else doD();
He is conviced that the second if-else pair is treated as a single entity, and that it is in fact nested under the first else.
I'm, however, sure that his code is equivalent to:
if(something) doA();
else if(something2) doC();
else doD();
This shows that the second else is not actually nested, but on the same level as the first if. I told him he needs to use curly braces to achieve what he wants to.
"But my code works as intended!"
And indeed, it worked as intended. Turns out the behavior of the code was the same, even if the else was not nested.
Surprisingly, I have found myself unable to write a clear and concise example that shows different behavior between
if(something) doA();
else
if(something2) doC();
else doD();
and
if(something) doA();
else {
if(something2) doC();
else doD();
}
Can you help me find an example that will show my colleague the difference between using/not using curly braces?
Or is the incorrect-looking version always equivalent to the one with curly braces, in terms of behavior?
Per C 2011 6.8.4 1, the grammar for a selection-statement includes this production:
selection-statement: if ( expression ) statement else statement
Per 6.8 1, a production for statement is:
statement: selection-statement
Thus, in:
if(something) doA();
else
if(something2) doC();
else doD();
the indented if and else form a selection-statement that is the statement that appears in the else clause of the preceding selection-statement.
The productions I have shown show that this is a possible interpretation in the C grammar. To see that it is the only interpretation, we observe that the text in the else clause of the initial selection-statement must be a statement, because there is no other production in the C grammar that produces an else keyword. (This is most easily seen by searching the grammar in clause A.2. Due to its size, I will not reproduce it here.) So we know the else is followed by a statement. We can easily see that the statement is a selection-statement, since it begins with if. Then the only question remaining is whether the next else is part of that if statement or not. Per 6.8.4.1 3, “An else is associated with the lexically nearest preceding if that is allowed by the syntax.”
Both structures come out to the same thing. The compiler
effectively sees the code as:
if ( something ) {
doA()
} else {
if ( something2 ) {
doC();
} else {
doD();
}
}
In practice, however, there is no different between this and:
if ( something ) {
doA();
} else if ( something2 ) {
doC();
} else {
doD();
}
The extra braces encapsulate a single statement, and you don't
actually need the braces when the if or the else controls
a single statement. (My first example puts every statement
except the encompassing if in braces.)
Logically, programmers tend to thing along the lines of the
second; languages where some sort of bracing ({},
BEGIN/END or indentation) is required almost always add an
elsif or elif keyword in order to permit this second form.
C and C++ (and Java, and C#, and...) don't, because the second
form works out without the extra keyword.
In the end, you don't want the extra indentation. (I've cases
with fifteen or twenty successive else if. That would make
for some serious indentation.) On the other hand, you do want
the controlled statement on a separate line. (Bracing is
optional: if your coding standard puts the brace on a separate
line, it's also conventional to suppress it if it only contains
a single statement.)

What is considered a statement in C++?

My professor commonly asks my class how many statements there are in a given program, but I can't determine what he defines as a statement. It seems as though an if/else is one statement, and a for loop is one statement regardless of if there are other supposed statements within it. Are there any governing rules for this matter or is his definition of his own invention?
Thanks
For a precise definition of a statement:
Definition: A statement is a block of code that does something. An assignment statement assigns a value to a variable. A for statement performs a loop.
In C, C++ and C# Statements can be grouped together as one statement using curly brackets
{
statement1;
statement2;
}
As far as counting statements, I agree with the others, there's not much point. Counting Lines of Code (LOC) though, actually has some value and there's a lot of research that tries to relate the number of LOC to the workload of developers. It's possible that your instructor is having you count statements and thinking of statements as nothing more than a single LOC, which isn't quite the case.
Statements nest, i.e. smaller statements can be joined into larger statements, like compound statements. For this reason, the question about "how many statements are there in this program" are ambiguous. One has to define the counting method first. Without it the question of "how many" makes little sense.
Here is the function that handles statements parsing in JS alike language:
static void do_statement(CsCompiler *c )
{
int tkn;
switch (tkn = CsToken(c)) {
case T_IF: do_if(c); break;
case T_WHILE: do_while(c); break;
case T_WITH: do_with(c); break;
case T_DO: do_dowhile(c); break;
case T_FOR: do_for(c); break;
case T_BREAK: do_break(c); CsSaveToken(c,CsToken(c)); break;
case T_CONTINUE: do_continue(c); CsSaveToken(c,CsToken(c)); break;
case T_SWITCH: do_switch(c); break;
case T_CASE: /*do_case(c);*/ CsParseError(c,"'case' outside of switch"); break;
case T_DEFAULT: /*do_default(c);*/ CsParseError(c,"'default' outside of switch"); break;
case T_RETURN: do_return(c); break;
case T_DELETE: do_delete(c); break;
case T_TRY: do_try(c); break;
case T_THROW: do_throw(c); break;
case '{': do_block(c, 0); break;
case ';': ; break;
default:
{
CsSaveToken(c,tkn);
do_expr(c);
break;
}
}
}
As you see it includes things like for, while and also expressions (separated by ;)
In computer programming a statement
can be thought of as the smallest
standalone element of an imperative
programming language. A program is
formed by a sequence of one or more
statements. A statement will have
internal components (e.g.,
expressions).
More at Statement (Computer Science) at Wikipedia.

In C/C++ why does the do while(expression); need a semi colon?

My guess is it just made parsing easier, but I can't see exactly why.
So what does this have ...
do
{
some stuff
}
while(test);
more stuff
that's better than ...
do
{
some stuff
}
while(test)
more stuff
Because you're ending the statement. A statement ends either with a block (delimited by curly braces), or with a semicolon. "do this while this" is a single statement, and can't end with a block (because it ends with the "while"), so it needs a semicolon just like any other statement.
If you take a look at C++ grammar, you'll see that the iteration statements are defined as
while ( condition ) statement
for ( for-init-statement condition-opt ; expression-opt ) statement
do statement while ( expression ) ;
Note that only do-while statement has an ; at the end. So, the question is why the do-while is so different from the rest that it needs that extra ;.
Let's take a closer look: both for and regular while end with a statement. But do-while ends with a controlling expression enclosed in (). The presence of that enclosing () already allows the compiler to unambiguously find the end of the controlling expression: the outer closing ) designates where the expression ends and, therefore, where the entire do-while statement ends. In other words, the terminating ; is indeed redundant.
However, in practice that would mean that, for example, the following code
do
{
/* whatever */
} while (i + 2) * j > 0;
while valid from the grammar point of view, would really be parsed as
do
{
/* whatever */
} while (i + 2)
*j > 0;
This is formally sound, but it is not really intuitive. I'd guess that for such reasons it was decided to add a more explicit terminator to the do-while statement - a semicolon. Of course, per #Joe White's answer there are also considerations of plain and simple consistency: all ordinary (non-compound) statements in C end with a ;.
It's because while statements are valid within a do-while loop.
Consider the different behaviors if the semicolon weren't required:
int x = 10;
int y = 10;
do
while(x > 0)
x--;
while(x = y--);
While I don't know the answer, consistency seems like the best argument. Every statement group in C/C++ is either terminated by
A semicolon
A brace
Why create a construct which does neither?
Flow control statement consistency
Considering consistency...
if (expr) statement;
do statement; while (expr);
for (expr; expr; expr) statement;
while (expr) statement;
...all these flow-control constructs, end with a semicolon.
But, countering that we can note that of the block-statement forms, only do while is semicolon delimited:
if (expr) { ... }
do { ... } while (expr);
for (expr; expr; expr) { }
while (expr) { }
So, we have ';' or '}', but never a "bare" ')'.
Consistency of statement delimiters
We can at least say that every statement must be delimited by ; or }, and visually that helps us distinguish statements.
If no semicolon were required, consider:
do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;
It's very difficult to visually resolve that to the distinct statements:
do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;
By way of contrast, the following is more easily resolved as a ; immediately after a while condition tells you to seek backwards for the do, and that the next statement is unconnected to that while:
do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;
Does it matter, given people indent their code to make the flow understandable? Yes, because:
people sometimes make mistakes (or have them transiently as the code's massaged) and if it visually stands out that means it will be fixed more easily, and
macro substitutions can throw together lots of statements on one line, and we occasionally need to visually verify the preprocessor output while troubleshooting or doing QA.
Implications to preprocessor use
It's also worth noting the famous preprocessor do-while idiom:
#define F(X) do { fn(X); } while (false)
This can be substituted as follows:
if (expr)
F(x);
else
x = 10;
...yields...
if (expr)
do ( fn(x); } while (false);
else
x = 10;
If the semicolon wasn't part of the do while statement, then the if statement would be interpreted as:
if (expr)
do-while-statement
; // empty statement
else
x = 10;
...and, because there are two statements after the if, it's considered complete, which leaves the else statement unmatched.
C is semicolon-terminated (whereas Pascal is semicolon-separated). It would be inconsistent to drop the semicolon there.
I, frankly, hate the reuse of the while for the do loop. I think repeat-until would have been less confusing. But it is what it is.
In C/C++ whitespace don't contribute to structure (like e.g. in python). In C/C++ statements must be terminated with a semicolon. This is allowed:
do
{
some stuff; more stuff; even more stuff;
}
while(test);
My answer is that, the compiler may get confusion, when we didn't include the semicolon in the termination of do.....while(); loop. Without this it is not clear about:
when the do ends?
If the while may a separate loop followed immediately after do loop.
That's why we include semicolon in the end of do......while loop, to indicate the loop is terminating here if the condition is false.

Is there ever a need for a "do {...} while ( )" loop?

Bjarne Stroustrup (C++ creator) once said that he avoids "do/while" loops, and prefers to write the code in terms of a "while" loop instead. [See quote below.]
Since hearing this, I have found this to be true. What are your thoughts? Is there an example where a "do/while" is much cleaner and easier to understand than if you used a "while" instead?
In response to some of the answers: yes, I understand the technical difference between "do/while" and "while". This is a deeper question about readability and structuring code involving loops.
Let me ask another way: suppose you were forbidden from using "do/while" - is there a realistic example where this would give you no choice but to write unclean code using "while"?
From "The C++ Programming Language", 6.3.3:
In my experience, the do-statement is a source of errors and confusion. The reason is that its body is always executed once before the condition is evaluated. However, for the body to work correctly, something very much like the condition must hold even the first time through. More often than I would have guessed, I have found that condition not to hold as expected either when the program was first written and tested, or later after the code preceding it has been modified. I also prefer the condition "up front where I can see it." Consequently, I tend to avoid do-statements. -Bjarne
Avoiding the do/while loop is a recommendation included in the C++ Core Guidelines as ES.75, avoid do-statements.
Yes I agree that do while loops can be rewritten to a while loop, however I disagree that always using a while loop is better. do while always get run at least once and that is a very useful property (most typical example being input checking (from keyboard))
#include <stdio.h>
int main() {
char c;
do {
printf("enter a number");
scanf("%c", &c);
} while (c < '0' || c > '9');
}
This can of course be rewritten to a while loop, but this is usually viewed as a much more elegant solution.
do-while is a loop with a post-condition. You need it in cases when the loop body is to be executed at least once. This is necessary for code which needs some action before the loop condition can be sensibly evaluated. With while loop you would have to call the initialization code from two sites, with do-while you can only call it from one site.
Another example is when you already have a valid object when the first iteration is to be started, so you don't want to execute anything (loop condition evaluation included) before the first iteration starts. An example is with FindFirstFile/FindNextFile Win32 functions: you call FindFirstFile which either returns an error or a search handle to the first file, then you call FindNextFile until it returns an error.
Pseudocode:
Handle handle;
Params params;
if( ( handle = FindFirstFile( params ) ) != Error ) {
do {
process( params ); //process found file
} while( ( handle = FindNextFile( params ) ) != Error ) );
}
do { ... } while (0) is an important construct for making macros behave well.
Even if it's unimportant in real code (with which I don't necessarily agree), it's important for for fixing some of the deficiencies of the preprocessor.
Edit: I ran into a situation where do/while was much cleaner today in my own code. I was making a cross-platform abstraction of the paired LL/SC instructions. These need to be used in a loop, like so:
do
{
oldvalue = LL (address);
newvalue = oldvalue + 1;
} while (!SC (address, newvalue, oldvalue));
(Experts might realize that oldvalue is unused in an SC Implementation, but it's included so that this abstraction can be emulated with CAS.)
LL and SC are an excellent example of a situation where do/while is significantly cleaner than the equivalent while form:
oldvalue = LL (address);
newvalue = oldvalue + 1;
while (!SC (address, newvalue, oldvalue))
{
oldvalue = LL (address);
newvalue = oldvalue + 1;
}
For this reason I'm extremely disappointed in the fact that Google Go has opted to remove the do-while construct.
The following common idiom seems very straightforward to me:
do {
preliminary_work();
value = get_value();
} while (not_valid(value));
The rewrite to avoid do seems to be:
value = make_invalid_value();
while (not_valid(value)) {
preliminary_work();
value = get_value();
}
That first line is used to make sure that the test always evaluates to true the first time. In other words, the test is always superfluous the first time. If this superfluous test wasn't there, one could also omit the initial assignment. This code gives the impression that it fights itself.
In cases such like these, the do construct is a very useful option.
It's useful for when you want to "do" something "until" a condition is satisfied.
It can be fudged in a while loop like this:
while(true)
{
// .... code .....
if(condition_satisfied)
break;
}
(Assuming you know the difference between the both)
Do/While is good for bootstrapping/pre-initializing code before your condition is checked and the while loop is run.
In our coding conventions
if / while / ... conditions don't have side effects and
varibles must be initialized.
So we have almost never a do {} while(xx)
Because:
int main() {
char c;
do {
printf("enter a number");
scanf("%c", &c);
} while (c < '0' || c > '9');
}
is rewritten in:
int main() {
char c(0);
while (c < '0' || c > '9'); {
printf("enter a number");
scanf("%c", &c);
}
}
and
Handle handle;
Params params;
if( ( handle = FindFirstFile( params ) ) != Error ) {
do {
process( params ); //process found file
} while( ( handle = FindNextFile( params ) ) != Error ) );
}
is rewritten in:
Params params(xxx);
Handle handle = FindFirstFile( params );
while( handle!=Error ) {
process( params ); //process found file
handle = FindNextFile( params );
}
It's all about readability.
More readable code leads to less headache in code maintenance, and better collaboration.
Other considerations (such as optimization) are, by far, less important in most cases.
I'll elaborate, since I got a comment here:
If you have a code snippet A that uses do { ... } while(), and it's more readable than its while() {...} equivalent B, then I'd vote for A. If you prefer B, since you see the loop condition "up front", and you think it's more readable (and thus maintainable, etc.) - then go right ahead, use B.
My point is: use the code that is more readable to your eyes (and to your colleagues'). The choice is subjective, of course.
First of all, I do agree that do-while is less readable than while.
But I'm amazed that after so many answers, nobody has considered why do-while even exists in the language. The reason is efficiency.
Lets say we have a do-while loop with N condition checks, where the outcome of the condition depends on the loop body. Then if we replace it with a while loop, we get N+1 condition checks instead, where the extra check is pointless. That's no big deal if the loop condition only contains a check of an integer value, but lets say that we have
something_t* x = NULL;
while( very_slowly_check_if_something_is_done(x) )
{
set_something(x);
}
Then the function call in first lap of the loop is redundant: we already know that x isn't set to anything yet. So why execute some pointless overhead code?
I often use do-while for this very purpose when coding realtime embedded systems, where the code inside the condition is relatively slow (checking the response from some slow hardware peripheral).
This is cleanest alternative to do-while that I have seen. It is the idiom recommended for Python which does not have a do-while loop.
One caveat is that you can not have a continue in the <setup code> since it would jump the break condition, but none of the examples that show the benefits of the do-while need a continue before the condition.
while (true) {
<setup code>
if (!condition) break;
<loop body>
}
Here it is applied to some of the best examples of the do-while loops above.
while (true) {
printf("enter a number");
scanf("%c", &c);
if (!(c < '0' || c > '9')) break;
}
This next example is a case where the structure is more readable than a do-while since the condition is kept near the top as //get data is usually short yet the //process data portion may be lengthy.
while (true) {
// get data
if (data == null) break;
// process data
// process it some more
// have a lot of cases etc.
// wow, we're almost done.
// oops, just one more thing.
}
It is only personal choice in my opinion.
Most of the time, you can find a way to rewrite a do ... while loop to a while loop; but not necessarily always. Also it might make more logical sense to write a do while loop sometimes to fit the context you are in.
If you look above, the reply from TimW, it speaks for itself. The second one with Handle, especially is more messy in my opinion.
Read the Structured Program Theorem. A do{} while() can always be rewritten to while() do{}. Sequence, selection, and iteration are all that's ever needed.
Since whatever is contained in the loop body can always be encapsulated into a routine, the dirtiness of having to use while() do{} need never get worse than
LoopBody()
while(cond) {
LoopBody()
}
I hardly ever use them simply because of the following:
Even though the loop checks for a post-condition you still need to check for this post condition within your loop so that you don't process the post condition.
Take the sample pseudo code:
do {
// get data
// process data
} while (data != null);
Sounds simple in theory but in real world situations it would probably turn out to look like so:
do {
// get data
if (data != null) {
// process data
}
} while (data != null);
The extra "if" check just isn't worth it IMO. I have found very few instances where it's more terse to do a do-while instead of a while loop. YMMV.
In response to a question/comment from unknown (google) to the answer of Dan Olson:
"do { ... } while (0) is an important construct for making macros behave well."
#define M do { doOneThing(); doAnother(); } while (0)
...
if (query) M;
...
Do you see what happens without the do { ... } while(0)? It will always execute doAnother().
A do-while loop can always be rewritten as a while loop.
Whether to use only while loops, or while, do-while, and for-loops (or any combination thereof) depends largely on your taste for aesthetics and the conventions of the project you are working on.
Personally, I prefer while-loops because it simplifies reasoning about loop invariants IMHO.
As to whether there are situations where you do need do-while loops: Instead of
do
{
loopBody();
} while (condition());
you can always
loopBody();
while(condition())
{
loopBody();
}
so, no, you never need to use do-while if you cannot for some reason. (Of course this example violates DRY, but it's only a proof-of-concept. In my experience there is usually a way of transforming a do-while loop to a while loop and not to violate DRY in any concrete use case.)
"When in Rome, do as the Romans."
BTW: The quote you are looking for is maybe this one ([1], last paragraph of section 6.3.3):
From my experience, the do-statement is a source of error and confusion. The reason is that its body is always executed once before the condition is tested. For the correct functioning of the body, however, a similar condition to the final condition has to hold in the first run. More often than I expected I have found these conditions not to be true. This was the case both when I wrote the program in question from scratch and then tested it as well as after a change of the code. Additionally, I prefer the condition "up-front, where I can see it". I therefore tend to avoid do-statements.
(Note: This is my translation of the German edition. If you happen to own the English edition, feel free to edit the quote to match his original wording. Unfortunately, Addison-Wesley hates Google.)
[1] B. Stroustrup: The C++ programming language. 3rd Edition. Addison-Wessley, Reading, 1997.
consider something like this:
int SumOfString(char* s)
{
int res = 0;
do
{
res += *s;
++s;
} while (*s != '\0');
}
It so happens that '\0' is 0, but I hope you get the point.
My problem with do/while is strictly with its implementation in C. Due to the reuse of the while keyword, it often trips people up because it looks like a mistake.
If while had been reserved for only while loops and do/while had been changed into do/until or repeat/until, I don't think the loop (which is certainly handy and the "right" way to code some loops) would cause so much trouble.
I've ranted before about this in regards to JavaScript, which also inherited this sorry choice from C.
Well maybe this goes back a few steps, but in the case of
do
{
output("enter a number");
int x = getInput();
//do stuff with input
}while(x != 0);
It would be possible, though not necessarily readable to use
int x;
while(x = getInput())
{
//do stuff with input
}
Now if you wanted to use a number other than 0 to quit the loop
while((x = getInput()) != 4)
{
//do stuff with input
}
But again, there is a loss in readability, not to mention it's considered bad practice to utilize an assignment statement inside a conditional, I just wanted to point out that there are more compact ways of doing it than assigning a "reserved" value to indicate to the loop that it is the initial run through.
I like David Božjak's example. To play devil's advocate, however, I feel that you can always factor out the code that you want to run at least once into a separate function, achieving perhaps the most readable solution. For example:
int main() {
char c;
do {
printf("enter a number");
scanf("%c", &c);
} while (c < '0' || c > '9');
}
could become this:
int main() {
char c = askForCharacter();
while (c < '0' || c > '9') {
c = askForCharacter();
}
}
char askForCharacter() {
char c;
printf("enter a number");
scanf("%c", &c);
return c;
}
(pardon any incorrect syntax; I'm not a C programmer)