Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am now in the midst of making a simple bytecode interpreter that uses RPN for expression notation and really postfix notation for anything, but now I've come to the question which is: can short circuit evaluation actually be used on postfix expressions? For example when evaluating the expression (false && (factorial(7) > factorial(5))) C++ knows the result of the && operator on the two operands evaluates to false before it even gets to the second operand, since (false && anything) is always equal to false. Now when you put this in RPN, you get (false (7 factorial 5 factorial >) &&).
I wanted to build an efficient RPN expression parser, so the problem is this: how do I make an efficient RPN expression parser with short circuit evaluation?
You would evaluate an RPN expression in two phases.
Phase 1: parse the RPN, and construct a tree representation of the RPN. So, in this tree, for example, the && node has two children nodes, for each half of the expression. Constructing this tree is a nearly identical process as evaluating the RPN, except for the evaluating part, which gets replaced by the operation of constructing a new node, and linking its child nodes to their new parent node, then pushing the parent node back on the RPN evaluation stack.
Phase 2: evaluate the constructed tree, using recursive descent. At this point, short-circuit evaluation becomes trivial: evaluate the left-hand child of a &&, then decide whether you actually want to evaluate the right-hand child.
Ditto for the || node, etc...
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Recently I have started looking into C++ from the basics and got to know (to my surprise) that I can give series of expressions in a single line separated by commas in some cases as below
//it'll execute all the expressions mentioned after condition seperated by comma
for(int i=0;condition;++i,++x,cout<<"in for loop"<<endl,z = z*2);
(x>y)? ++z,z1 = z*2, cout<<"printing statement"<<endl:cout<<"condition failed"<<endl,z = z/2;
Here, I have a confusion after this is working. Is it safe to code in that way or is there any problem coding in such a way?
Please clarify!!!
Correct me if i'm wrong anywhere, I'm just curious to know why most of the programmers don't use this way (I haven't seen such kind of lines anywhere)
The comma operator , evaluates each of its operands in sequence. In standardese, there is a sequence point between the evaluation of the left operand and the right operand.
In a expression which contains a comma operator, the value of the left operand is discarded and the expression takes on the value of the right operand. In both of the examples above, the comma operator is used in a void context, so none of the values are used.
So a statement like this where the value of the comma operator is not used:
exp1, exp2, exp3, exp4;
Is equivalent to the following sequence of statements:
exp1; exp2; exp3; exp4;
The first example is equivalent to the following:
for(int i=0;condition;) {
++i;
++x;
cout<<"in for loop"<<endl;
z = z*2;
}
And the second example:
if (x>y) {
++z;
z1 = z*2;
cout<<"printing statement"<<endl;
} else {
cout<<"condition failed"<<endl;
z = z/2;
}
Note that this is considerably more readable that the one-line versions. It's also easier to debug. Since debuggers typically step through code a line at a time, it breaks up the flow and is more granular.
Not indenting and spacing your code is not less costly regarding performance. It is unreadable, confusing and a pain to understand for you and for anyone who'd have to work with it.
Lot of people will prefer a well-syntaxed, beautifully and efficiently-indented code than a top-performance one. You can modify, debug and refract a code which might not work but has the advantage to be understandable.
On the other hand, very few codes remain unchanged and stay unread. There will always be a time when someone, may be you, will have to read it again and if it looks like the one if your OP, it will be very time costly to do.
It is allowed. In my opinion and i say without a reference that in general other programmers do not find your 'for' loop very readable. Sometimes in a for loop you want to do other things then just for (int i = 0; i < 10; ++i){"do something"}For example increment 'i' in every loop with two. Reading code should be like reading a text. If you are reading a book you do not want it to be unnecessary difficult.
Your other question was about the safety of the statement. The biggest problem with the code is that you might get confused about what you are doing exactly. Bugs are caused by human errors (computers are deterministic and are executing machine code which ultimately has been written by a human) and the question about safety mainly depends on how you define it.
To give you some tips. When i just started programming C++ i looked a lot on CPP reference. I will give you a link where you can read about the syntax and what is allowed/possible. On this website there are quite a lot of examples on all kinds of statements. They will in general not put 5 or 6 operations within in a single line. If there are more variables that you want to change then you might want to do that in the scope of the for loop so it will be more readable instead of inside the for loop.
http://en.cppreference.com/w/cpp/language/for
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The error message appears on Xcode that says "invalid operands to binary expression.
in my code I'm using an array of a struct, i'm trying to sort input data in an ascending order, and i'm getting this error message at the "if" condition shown in the print screen at this link:
https://www.dropbox.com/s/0mch2gbxcif0a20/Screen%20Shot%202016-04-27%20at%2012.45.45%20PM.png?dl=0
The Code
if (studentsInfo[i] > studentsInfo[i + 1]) {}
The Error
Invalid operands to binary expression ('students' and 'students')
What do you compare in your program? As I see, you have to compare names, but all you do is compare an array element which is a struct data type.
If you are trying to compare names, you have to use dot "." operator to reach names. After yo compare names, you can change the elements's place.
The error means that > only takes two arguments and you are using it for something else. In this case you are comparing an entire data structure that does not have an override for > operator and is an undefined behavior. StudentsInfo[i] is a data structure that has more than one element in it. Replace the StudentsInfo[i] with StudentsInfo[i].GPA or another element whose data type has a defined > operator.
This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 8 years ago.
I want to execute a multi condition if statement like below.
Head* head;
If ((head->next!=NULL)&&(head->next->next!=NULL))
The order of execution is important for the above statement to work without seg fault.
Is there a way to determine with way a compiler executes it, at compile time.
The standard.
You're guaranteed the first expression will be evaluated first.
Furthermore, you're guaranteed that if the first evaluates to false, the second won't be evaluated (look up short-circuiting). If this doesn't happen, the compiler isn't compliant.
The order is always left to right. Thus
(cond1) && (cond2)
will always end up test cond1 first, and, if that's true, cond2.
The && and || operators force left-to-right evaluation and introduce a sequence point, so you are guaranteed that the LHS will be fully evaluated and all side effects applied before the RHS is evaluated.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am currently trying to build a very simple compiler. I have created a function that converts a mathematical equation in infix notation to RPN using the shunting-yard algorithm however I have encountered a problem. I did not include error checking in my conversion function so I was wondering if there was a simple way to check if a function in infix notation is in correct infix notation syntax. This would enable me to keep my current conversion function without obscuring it with error checking.
If your expressions only consist of parentheses, values (constants and/or identifiers), and prefix, postfix and infix operators, then there are two error conditions you need to check:
The parentheses must match. It's hard not to notice this with the shunting yard algorithm, because there is a point in the algorithm where an open parenthesis is popped off the stack when a close parenthesis is encountered in the input. If you overpop the stack or you don't pop the entire stack at end of input, then the parentheses didn't balance.
The tokens must conform to the following simple regular expression:
PRE* VAL POST* ( INFIX PRE* VAL POST* )*
where
PRE is a prefix operator or an (
POST is a postfix operator or a )
VAL is a value: a constant or an identifier
That actually reduces to a two-state state machine: the initial state (state 0) could be called "expecting value" and the other state (state 1) could be called "expecting operator". Only state 1 is accepting, and the transitions are as follows:
State 0:
PRE → State 0
VAL → State 1
State 1:
POST → State 1
INFIX → State 0
All other transitions are to an error.
It's often necessary to implement this state machine in order to properly deal with unary minus (and other operators which could be prefix or infix), and it is, in any event, very simple to integrate into your input handling.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've faced lines of code
int a=6, b=7;
cout << (b,a);
it prompt out 16.
What is (b,a) mean? Does it do a operation?
In this expression
(b,a)
there is the comma operator. Its value is the value of the last (right) subexpression after the comma. The value of the first (left) subexpression is discarded. So the output will be
6
From the C++ Standard
A pair of expressions separated by a comma is evaluated left-to-right;
the left expression is a discardedvalue expression (Clause 5).87 Every
value computation and side effect associated with the left expression
is sequenced before every value computation and side effect associated
with the right expression. The type and value of the result are the
type and value of the right operand; the result is of the same value
category as its right operand, and is a bit-field if its right operand
is a glvalue and a bit-field. If the value of the right operand is a
temporary (12.2), the result is that temporary.