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.
Related
#include<iostream>
using namespace std;
int main(){
char c = 'a';
int numb;
for (int i = 1; i <= 25 ; i++){
cout << c << "," << c++ << endl;
}
}
Why is it that when I print the output above, the following will get printed:
b,a
c,b
d,c
But I was expecting:
a,b
b,c
c,d
If you are not compiling to the C++17 Standard revision or more recent you have encountered undefined behaviour. The older C++ Standards do not specify the sequencing of
cout << c << "," << c++ << endl;
so there are no guarantees on when that c++ will occur. The only thing you can count on is the c++ term will be the initial value because ++ increments after the value is collected.
a,a
or
b,a
are valid outputs.
As of C++17 the Standard guarantees that all side effects will be resolved before proceeding to the next <<. << c will be resolved, not that there is much to resolve, before << "," starts. << c++ comes even later in the chain. This means you should always see
a,a
b,b
c,c
See the notes on Undefined Behaviour at the bottom of Order of evaluation
I believe that it has to do with the order of operations here. The stream operator (<<) operates from right to left. Meaning that in the first run, c++ evaluates to "a", but causes c to be iterated up to "b".
I wrote the following program to search of a particular string in a given array of string. I made an error in the search function and wrote i-- instead of i++.
#include <iostream>
#include <string>
using namespace std;
int search(string S[], int pos, string s)
{
for(int i=0; i<pos; i--) {
cout << i << " : " << S[i] << "\n";
if (S[i] == s) {
cout << "Inside Return ->\n";
cout << i << " / " << S[i] << " / " << s << "\n";
return i;
}
}
return -1;
}
int main()
{
string S[] = {"abc", "def", "pqr", "xyz"};
string s = "def";
cout << search(S,2,s) << "\n";
return 0;
}
Logically the loop is an infinite loop and should not stop but what I observed was that the if condition was true for each search and the function returned -1.
I printed the values and noticed that the value of S[-1] is always same as the third argument passed to the function (the string to be searched) due to which the loop was returning -1 every time.
Is this something that g++ is doing or is it related to the way memory is allocated for the formal arguments of the function?
Output of the above code -
0 : abc
-1 : def
Inside Return ->
-1 / def / def
PS - I am using g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Edit -I understand that g++ doesn't check for bounds but I was intrigued by the fact that the values of S[-1] was always the same as s. I was wondering if there are any possible theories for this
Access out of bounds is undefined behaviour.
Undefined behaviour reads is not "garbage" or "segfault", it is literally anything. The read could time travel and make code earlier in the program behave differently. The behaviour of the program, from start to finish, it completely unspecified by the C++ standard whenever any undefined behaviour happens anywhere.
In this case, naive assembly and the ABI tells you that arguments on the "stack" at run time are located adjacent to things like the arguments to the function.
So a naive rewriting of your code into assembly results in negative indexes reading from the arguments to the function.
But, a whole myriad of completely innocuous, common and safe alternative interpretations of your program as machine code, starting with inline and going far away from there, make this not happen.
When compiling without LTO or over dynamic library boundaries, you can have some small amount of confidence that the compiler's published ABI will be used to make the call; any assumption elsewhere is dangerously bad. And if you are compiling without LTO and relying on it, it now means that you have to audit every build of your code from now until eternity or risk a bug showing up with no apparent cause long from now.
I have an assignment where I need to create a postfix calculator. I'm running into some difficulties that previous questions regarding the subject on SO didn't cover adequately.
Here's an example of input I want to handle:
12 6 +
2 *
[Carriage return]
Result: 36
The description of the assignment:
The arithmetical expressions we normally use are infix expressions, meaning that the operator appears between its two operands, as in "4 + 5". In postfix expressions, the operator appears after its operands, as in "4 5 +". Here is a slightly more complex postfix expression: "25 12 7 - 2 * /". The equivalent infix expression is: "25 / ((12 - 7) * 2)". The result of that expression should be 2.5 (don't use integer division). Postfix expressions don't require parentheses.
Write a program that uses a stack to evaluate postfix expressions.
Each input expression should be entered on its own line, and the
program should terminate when the user enters a blank line. The only
symbols in an expression will be +, -, *, /, digits and spaces.
Hint: Read a postfix expression from left to right. When you read a
number, push it on the stack. When you read an operand, pop the top
two numbers off the stack, apply the operator to them, and push the
result on top of the stack. At the end, the result of the expression
should be the only number on the stack.
Here's my code so far:
#include <list> /* Linked Lists */
#include <stack> /* Stacks */
#include <iostream> /* cout cin */
int main() {
std::stack< double, std::list<double> > postfixStack;
std::string input;
std::cout << "Enter a postfix expression: ";
std::getline(std::cin, input);
while (input != "") {
std::cout << "Input expression: " << input << std::endl;
for (int i = 0; i<input.length()-1; i++) {
if (input.compare(i, 1, " ")) { // should ignore spaces, but doesn't
std::cout << "Skipping element " << i << " \n";
} else if (static_cast<int>(input[i]) == input[i]) { // push numbers onto the stack
postfixStack.push(static_cast<double>(input[i]));
std::cout << "Pushing " << input[i] << " onto the stack.\n";
} else if (input.compare(i, 1, "+")) { // pop two numbers off the stack (1), apply the operator to them (2), and push that onto the stack (3)
double operand1 = postfixStack.top();
postfixStack.pop();
double operand2 = postfixStack.top();
postfixStack.pop();
postfixStack.push(operand1 + operand2);
std::cout << "Adding " << operand1 << " and " << operand2 << std::endl;
}
}
std::getline(std::cin, input);
}
if (!postfixStack.empty()) {
std::cout << "Result of expression: " << postfixStack.top() << std::endl;
} else {
std::cout << "It appears that you did not enter an expression to evaluate.\n";
}
return 0;
}
Syntax highlighting and line numbers on Gist.
Where I'm struggling:
My while loop should allow more than one line of input per the spec. I was originally using cin instead of getline, but that presented the opposite problem: unlimited lines to enter anything whatsoever, even when checking for /r and the empty string.
I'm trying to skip over spaces in my loop, but instead my conditional appears to skip over anything that isn't a space.
Checking string subscripts means that I can only use numbers with one digit, which definitely isn't what I want. When I encounter a number: I think I could check the next element, if that's a number then I could concatenate them and bump up the loop counter. In theory, at least. I'd like to get basic functionality before I work on that.
My while loop should allow more than one line of input per the spec.
You've already found getline. You can simply use that to read whole lines. That approach you've taken looks fine.
I'm trying to skip over spaces in my loop, but instead my conditional appears to skip over anything that isn't a space.
That's right. You're checking the result of string::compare, but the result isn't a boolean, and non-zero doesn't mean the strings are equal, it means they aren't equal.
The way you've performed the comparison is uncommon, BTW, and more usual would be to simply compare the character to ' ', or to use isspace or maybe isblank.
Checking string subscripts means that I can only use numbers with one digit, which definitely isn't what I want.
Right. When you see a digit, you can enter a nested loop to read all subsequent digits. The base case, a one-digit string, is trivially converted to a number. (But just a tad less trivial than you think, see the note below.) And if you know how to determine the value of an N-digit string (let's say ABC), you can determine the value of an N+1-digit string (let's say ABCD) by multiplying by 10, and adding the value of the next digit.
Note: static_cast<int>(input[i]) == input[i] is always true. This doesn't mean what you think it means. Use your debugger to inspect the value of static_cast<int>(input[i]) for some characters, and try to understand what this cast is doing. When you understand what this does, think about another check you could do instead, and how you can use that, after checking a character is a digit, to determine the numeric value of that digit.
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.
I'm using the book "Programming Principles and Practice using C++" to learn programming and one of the exercises is looping through the characters a-z using a while-loop.
Now, I have programmed with C++ and other languages before, so I decided to try to use as few lines as possible (while still using a while-loop). However, this came with the cost of my output being kind of messed up.
Code:
#include <iostream>
int main(){
char ch = 'a';
while(ch <= 'z')
std::cout << ch << '\t' << (int) ch++ << std::endl;
return 0;
}
Output:
b 97
c 98
d 99
e 100
...
x 119
y 120
z 121
{ 122
Now I do realize that this could've been done with a for-loop instead, and I did that as well (it worked). But I still don't get what's wrong with this code, and it's really annoying me.
It appears as if I've told it to output "ch+1", since it prints out 'b' where it should print 'a'. The incrementing isn't done until after the integer value of ch has been put into the out-stream (post-increment). And even if I had incremented it earlier, at least the printed characters and their integer values should correspond.
Any ideas of why this code isn't working?
The order of the operator<< calls is well-specified, but the order in which their operands is evaluated is not.
The increment of ch may happen before or after you output ch "the first time", and merely running this program is Undefined anyway because of the interleaved read/write operations:
[2003: 1.9/12]: A full-expression is an expression that is not a
subexpression of another expression. [..]
[2003: 1.9/16]: There is a sequence point at the completion of
evaluation of each full-expression.
[2003: 5/4]: Except where noted, the order of evaluation of operands
of individual operators and subexpressions of individual expressions,
and the order in which side effects take place, is unspecified.
Between the previous and next sequence point a scalar object shall
have its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be accessed only to
determine the value to be stored. The requirements of this paragraph
shall be met for each allowable ordering of the subexpressions of a
full expression; otherwise the behavior is undefined.
Instead, be explicit:
std::cout << ch << '\t' << int(ch) << std::endl;
++ch;
Your compiler should have warned you about your code. That it didn't indicates that you do not have your diagnostics set at a useful level.
With GCC, use -Wall -Wextra -std=c++98 -pedantic (or -Wall -Wextra -std=c++0x -pedantic for C++0x).
Short answer is that you have a bit of Undefined Behavior because you're both modifying and using the value of the variable ch, via separate sub-expressions, in the same expression.
The Right Thing(TM) to do here is to use the most practical loop for the task at hand:
#include <iostream>
int main(){
for(char ch = 'a'; ch <= 'z'; ++a){
std::cout << ch << '\t' << ch+0 << std::endl;
}
}
The ch++ in your code gets evaluated first. A more readable and correct version would be:
#include <iostream>
int main(){
char ch = 'a';
while(ch <= 'z') {
std::cout << ch << '\t' << int(ch) << std::endl;
++ch;
}
return 0;
}
When you use one variable twice in one command or expression, once with ++ (or --) and once without, you get undefined behavour.
Instead use:
while(ch <= 'z')
{
std::cout << ch << '\t' << (int) ch << std::endl;
ch++;
}