This question already has answers here:
Semicolon at the ends of if-statements and functions in C
(7 answers)
Closed 5 years ago.
#include <iostream>
int main() {
for( int i = 0; i < 5; ++i) {
std::cout << "Hello" << std::endl;
};
}
Is there any case that the semicolon after the for loop would affect the program ?
The semicolon is an empty expression statement.
From section 6.2 of the C++ standard
The expression is a discarded-value expression (Clause 5). All side
effects from an expression statement are completed before the next
statement is executed. An expression statement with the expression
missing is called a null statement. [ Note: Most statements are
expression statements — usually assignments or function calls. A null
statement is useful to carry a label just before the } of a compound
statement and to supply a null body to an iteration statement such as
a while statement (6.5.1). —end note ]
This will be more clear with some reformatting:
#include <iostream>
int main(){
for(int i=0; i<5; ++i){
std::cout <<"Hello"<<std::endl;
}
;
}
The presence of this null statement has no effect on the program.
No.
The semicolon is not even "attached" to the loop; it's just an empty statement sitting there, effectively on its own.
It doesn't change anything. It just evaluates to an empty statement.
It's completely harmless. Just a bit of pointless clutter.
Related
This question already has answers here:
Defining a variable in the condition part of an if-statement?
(5 answers)
Closed 1 year ago.
Consider this code:
if (int* p = nullptr) {
}
else {
std::cout << *p << std::endl;
}
This compiles with clang 7.0.1 with -std=c++17, -Wall, -Wextra and -pedantic-errors without a single warning generated.
I've got two questions:
How is this possible? I always thought that scope of such variables ends with the if-block. I'd be thankful for quotation from the standard if possible.
If it's legal though, shouldn't it at least generate a warning? Are there any reasonable applications of such feature?
Why is variable declared in an if-statement still in scope in else block?
Because the standard says that it is. It was designed so presumably because it is useful.
How is this possible?
It's unclear why it wouldn't be possible.
I always thought that scope of such variables ends with the if-block.
You assumed wrongly.
I'd be thankful for quotation from the standard if possible. [language-lawyer]
Latest draft says:
[stmt.select.general]
Selection statements choose one of several flows of control.
selection-statement:
...
if constexpropt ( init-statementopt condition ) statement else statement
...
Note that the entire if (condition) statement else statement is a selection-statement.
[basic.scope.block]
Each
selection or iteration statement ([stmt.select], [stmt.iter]),
...
introduces a block scope that includes that statement or handler.
Note that the condition is directly within the if-statement and not inside a sub-statement, and thus a declaration within it extends until the end of the entire block scope, which contains both the if-sub-statement, and the else-sub-statement (not standard names for those sub-statements).
There is also a pretty clear example that demonstrates ill-formed re-declarations, and incidentally shows the scope of such declaration:
if (int x = f()) {
int x; // error: redeclaration of x
}
else {
int x; // error: redeclaration of x
}
If it's legal though, shouldn't it at least generate a warning?
Yeah, it would be nice if compilers were able to detect all provable null pointer indirections at compile time. It may be worth submitting a feature request regarding this corner case.
Are there any reasonable applications of such feature?
Sure. Following fabricated example seems reasonable to me:
if (Response r = do_request()) {
log << "great success. content: " << r.content;
} else {
log << "someone broke it :( error: " << r.error_code;
}
Or if you dislike implicit conversions:
if (Response r = do_request(); r.is_success()) {
This question already has answers here:
Are compound statements (blocks) surrounded by parens expressions in ANSI C?
(2 answers)
Closed 4 years ago.
I have the following code:
int main() {
int i=0;
int j=({int k=3;++i;})+1; // this line
return 0;
}
It compiles and runs. If I remove the () from "this line", then it doesn't compile.
I'm just curious what syntax rule is being applied here.
The {} contains 2 statements, and the last statement indicates the "return" value of this code block. Then why does it need an extra () pair to make this return value usable?
That's a statement expression, and it's a GCC-specific extension.
From the linked reference:
A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.
A compound statement is a curly-brace enclosed block of statements.
This question already has answers here:
Why are empty expressions legal in C/C++?
(11 answers)
Closed 7 years ago.
Why does the C/C++ parser not report an error on a semicolon when it is used alone? For example:
int a;
;
int b;
Is it a consequence of language grammar rules or is it a consequence of parsing algorithms? What do standards say about such a case? Whether ; or e.g. int; should be allowed?
Consider the classic string copy function from K&R:
void strcpy(char *src, char *dst)
{
while (*src++ = *dst++);
}
As you can see the empty statement is not just legal, it's one of foundations of the short C syntax.
A semicolon terminates a statement.
If your statement doesn't do anything, that's your prerogative as a programmer.
An example of a completely valid use of an empty statment:
for (int x = 0;; x++) {
if (something(x)) {
return 5;
}
if (bah(x)) {
continue;
}
if (otherthing(x)) {
return 3;
}
}
The middle statement in the for loop is empty. But it is still necessary, as the for loop takes three distinct statements, and the first and third are populated.
I don't see a good reason why a lone semicolon should be invalid; it does no harm. It is allowed by all relevant C/C++ standards, which is not a worse position than it not being allowed.
It's specified in the standard, §6/1 and §6.2/1 (revision N3376):
statement:
...
attribute-specifier-seq_opt expression-statement
...
and
expression-statement:
expression_opt;
So a statement can be an expression statement with a colon and optionally a expression and an attribute specifier sequence before.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 8 years ago.
In c++, arguments evaluation of order is not guaranteed, but is the order of left/right sub expression of assignment expression is guaranteed? For example
#include <iostream>
#include <map>
int main()
{
int i = 2;
std::map<int, int> map;
map[i++] = i--;
return 0;
}
Is left expression i++ guaranteed to be executed before right expression i--?
You asked:
Is left expression i++ guaranteed to be executed before right expression i--?
No, it is not.
The line
map[i++] = i--;
could end up being
map[2] = 3;
or
map[1] = 2;
depending on which side of the assignment operator gets evaluated first.
However, since the line invokes undefined behavior, it could also be, as pointed out in the comment by #juanchopanza, :
map[42] = -999;
This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
When I use two variables in a for loop with different conditions two conditions like I have used below i<3,j<2 the for loop is always executing till the second condition fails.
#include<iostream>
#include<conio.h>
using namespace std ;
int main()
{
int i,j ;
for(i=0,j=0;i<3,j<2;i++,j++)
{
cout<<"hello" ;
}
getch() ;
return 0 ;
}
In that code, hello is printed 2 times. Why?
If I use i<3,j<10, "Hello" is printed 10 times. I can't understand why the first condition is being neglected. Is it compiler dependent or something else?
Every thing works normal if I replace with conditions like || (OR) or &&(AND).An other thing is that I cannot initialize i and j in the for loop itself, it is showing me an error, but works fine when I declare variables in C style or one variable outside the for loop, why is it so?
Compiler I have used is Orwell Dev C++.
Thanks in advance.
for(i=0,j=0;i<3,j<2;i++,j++)
is equivalent to
for(i=0,j=0;j<2;i++,j++)
The comma expression takes on the value of the last expression.
Whichever condition is first, will be disregarded, and the second one will be used only.
The for loop consists of:
for(START_STATEMENT; CONDITION_EXPRESSION, LOOP_EXPRESSION) BODY_BLOCK
Where:
START_STATEMENT is any single statement, which may include variable declaration. If you want to declare 2 variables, you can write int i=0, j=0, but not int i=0; int j=0 because the latter are actually 2 statements. Also node, that variable declaration is a part of statement, but cannot be a part of (sub) expression. That is why int i=0, int j=0 would also be incorrect.
CONDITION_EXPRESSION is any single expression that evaluates to a boolean value. In your case you are using a coma operator which has the following semantics: A, B will do:
evaluate A (it will evaluate, not just ignore)
ditch the result of A
evaluate B
return B as the result
In your case: i<3,j<2 you are comparing i<3, you are just ignoring the result of this comparison.
Comma expressions are useful when the instructions have some side effects, beyond just returning a value. Common cases are: variable increment/decrement or assignment operator.
LOOP_EXPRESSION is any single expression that does not have to evaluate to anything. Here you are using the comma expression again, ignoring the result of the left-hand-side. In this case however, you are not using the result anyway, and just using the ++ side effect - which is to increment the values of your variables.
BODY_BLOCK is either a single statement or a block, encapsulated with curly braces.
The above for can be compared to:
{
START_STATEMENT;
while(EXPRESSION) {
BODY_BLOCK;
LOOP_EXPRESSION;
}
}
The c complier always used second condition.
therefore j<2 is used.
use this for loop
for(i=0,j=0;j<10;i++,j++)