This question already has answers here:
Cannot understand for loop with two variables [duplicate]
(3 answers)
Closed 6 years ago.
This compiles and runs, but produces garbage values for "a". Why doesn't "a" increment like "b"? Why is it producing garbage?
for(a,b=0; a,b != 55; a,b++)
{
//outputs garbage
std::cout << "a = " << a << std::endl;
//outputs expected results
std::cout << "b = " << b << std::endl;
}
The comma operator says execute the expression on the left then execute the expression on the right:
a, b=0
first executes a which does nothing, then it executes b=0 which assigns zero to b.
Why does the comma operator exist? The comma operator can be useful when the expressions have side effects.
It also serves a sequence point which tell the compiler "everything on the left must be complete before anything on the right happens. This constrains the optimizations allowed by the compiler, so for example a += 1, b = a + c[a] will always add one to a before using it as an index. Something like b = ++a + c[a] is undefined because the compiler can increment a before or after it uses it as an index.
Related
This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 6 years ago.
I am trying to assign part of a QVector double array to complex double array in Qt.
Running the following code, I have the problem that std::cout << y.at(i) << std::endl; correctly prints a 16-bit integer value but std::cout << y1[i] << std::endl; prints zeros: (0,0) (0,0) (0,0) ...
I would like the result (y[0],0) (y[1],0) (y[2],0)...
Please can someone advise what is wrong?
QVector<double> x(100), y(100); // Original QVector
std::complex<double> y1[100];
int i=0;
while(i<101)
{
// get y values from somewhere else (quint8 data8)
y[i] = (256.0*data8[2*i]) + 1.0*data8[2*i+1];
std::cout << y.at(i) << std::endl;
y1[i] = (y.at(i),0.0);
std::cout << y1[i] << std::endl;
i++;
}
Let's look at this expression:
(y.at(i), 0.0)
In C++ parentheses are just a grouping technique, which is used for operator precedence designation. For example, if you execute 2*2+2, you'll get six. But if you want to get eight, you need parentheses: 2*(2+2). So you assignment line is equivalent to:
y1[i] = y.at(i), 0.0;
Why does it compile and what does it mean? It compiles because a comma operator is used. In C++, comma is a binary operator with a very simple action: it computes it's left-hand argument, throws the result away, then computes it's right-hand argument and returns the result. So in your case it discarded y.at(i) and returned zero, which was successfully assigned to y1[i]. The shortest way to do what you want in modern C++ is to use initializer lists:
y1[i] = {y.at(i),0.0};
If you have an ancient compiler, it's just a bit more verbose:
y1[i] = std::complex<double>(y.at(i), 0.0);
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 6 years ago.
I want to write several lines to a file. Each line has an index (running index).
My code is:
ofstream outputFile;
int index = 0;
outputFile << ++index << ") FirstLine" <<endl
<< ++index << ") SecondLine" <<endl
...
<< ++index << ") LastLine" <<endl;
Problem is that I get no running index. That is, all lines has the same index (which is the total lines number). So my questions are firstly, how does ofstream work (meaning why do I get the described result). Secondly, what should I do to get it work?
Firstly, how does ofstream work (meaning why do I get the described result)?
According to the C++ standard (section 1.9, clause 15):
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent, the behavior is undefined.
Applied to your case:
The evaluation of the ++index statements (which are operands to the << operator) is unsequenced.
++index modifies the value of index, and therefore has a side effect on a scalar object.
As such, the behavior is undefined.
Secondly, what should I do to get it work?
One simple option would be to split the single large output expression into multiple lines, such that each ++index statement is on a separate line.
Alternatively, you could both solve the problem and reduce repetition by using a loop.
For example:
#include <array>
#include <iostream>
#include <string>
int main () {
static const std::array<std::string, 3> lines = {
"First line",
"Second line",
"Last line",
};
for (int i = 0; i < lines.size(); ++i) {
std::cout << i + 1 << ") " << lines[i] << std::endl;
}
}
Save this as example.cc, and compile using:
clang++ -std=c++14 example.cc -o example
Then run the example:
$ ./example
1) First line
2) Second line
3) Last line
Note that this prints to standard output to simplify the example, but std::cout can be easily replaced with an instance of std::ofstream depending on your use case.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 7 years ago.
The following code gives a weird output. I have tried it on multiple compilers and ended up with the same answer. It will process the statement right to left but print the output left to right however c++ statements are evaulated left to right in general. Can someone explain why this happens when we overload the cout statement.
Output:
15
10
5
However the Output if processed from left to right should be:
8
10
12
#include<iostream>
using namespace std;
int main(){
int a = 5, b = 3, c = 2;
cout<< (a = b + a) << endl << (b = c + a) << endl << (c = b + c);
return 0;
}
This will result in unspecified behavior. The order in which the operations execute isn't specified (since there are no sequence points between them), so the three assignments
a = b + a
b = c + a
c = b + c
can occur in any order. Therefore the output from cout is also unspecified .
This question already has an answer here:
The output of cout << 1 && 0;
(1 answer)
Closed 7 months ago.
Consider:
int i = 56, j = 0;
int n = i&&j;
cout << i&&j;
cout << endl << n;
whose output would be:
56
0
I imagine it's either because of operator precedence or logical short circuit, but I can't seem to figure out which, or the reason.
The expression cout << i&&j is equivalent to (cout << i) && j. Both operands are evaluated and converted to bool. The statement as a whole has no effect, but the evaluation of the subexpression cout << i has the usual side effects, of course, namely writing something to the standard output.
The && operator is indeed short-circuited and j is only evaluated if cout << i evaluates as true. This condition is equivalent to cout.good(), which is usually the case (unless you somehow managed to close your standard output).
As you expected, the << operator comes takes precedence over &&.
Thus, cout << i&&j first outputs i, then compares the returned stream to j (both are true, so the returned value is true, but this value is discarded).
See here for the full list of operator precedence.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
pre and post increment operations on a variable give different output on TC and gcc [duplicate]
(5 answers)
Closed 9 years ago.
int a = 0;
cout << a << a+1 << a << 1+a << a;
// output is 01010 , ok fine i understand it! :-)
cout << endl;
cout << a << ++a << a << a++ << a;
// output is 22202 ,
// Plzzz help me how compiler interprets my this statement
// i cant understand :-(
int x = 1;
cout << ++x + ++x;
// output is 6
// how ??
Please if anyone could explain it to me how these outputs are coming :-)
Thanks in Advance!
It depends on the type of x. If x is a built-in type (e.g., int) then you have undefined behavior because you're modifying x twice without an intervening sequence point1.
If x is a user-defined type, then you have unspecified behavior.
1. Technically C++11 has change the terminology so "sequence point" is no longer used, bu the effect is the same.