How does "()" convert statements into expressions in C++? [duplicate] - c++

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.

Related

What is the scope and evaluation of this if [duplicate]

This question already has answers here:
Declaring and initializing a variable in a Conditional or Control statement in C++
(9 answers)
Defining a variable in the condition part of an if-statement?
(5 answers)
Closed 1 year ago.
When cleaning up some code that I have found online, I came across with this weird c++ line:
if (int i = 1) std::cout << i;
With LLVM it compiled fine and the console output is 1, but how does the scope is handled in here, shouldn't the i variable be only accessible inside the conditional (inside the parenthesis)? And how is that possible to be evaluated to true, isn't an assignment a void operation and with no value, so 0/false? What is going on with this line?

semicolon after the for loop block [duplicate]

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.

Why is a semicolon by itself allowed in C/C++? [duplicate]

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.

Cannot understand for loop with two variables [duplicate]

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++)

Unsure what this while statement is doing [duplicate]

This question already has answers here:
How does the Comma Operator work
(9 answers)
Expression "variable, variable = value;"
(4 answers)
Closed 9 years ago.
So, I'm doing homework. I've encountered something I haven't seen before and cannot find a decent explanation of what it does. Basically,
Object object;
...
while((value1, value2) = function(object)) {
object.foo(value1, value2);
}
The (value1, value2) in the while statement really throws me. Any ideas?
Its a comma operator.
The result of the comma operator is the last value (the others are evaluated and discarded).
while((value1, value2) = function(object)) {
object.foo(value1, value2);
}
If value1 is just a variable and not an expression then it is equivalent too:
while(value2 = function(object)) {
object.foo(value1, value2);
}
If value1 is an expression then it is evaluated each time around the loop. The result is discarded, but if the expression has side effects these will take effect.