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 last month.
Improve this question
On today's adventofcode, we had a pathfinding problem, with persistent states over multiple rounds.
I created a function called solve(startPoint, endPoint) which would calculate the steps to go from one waypoint to the other.
The code that worked fine:
int first = solve(start, end);
int second = solve(end, start);
int third = solve(start, end);
return first + second + third;
The code that did not work:
return solve(start, end) + solve(end, start) + solve(start, end);
And neither did
return (((solve(start, end)) + solve(end, start)) + solve(start, end));
How can I return the accumulated value in one line, without running in some sort of order issue?
The order of parts of a composed expression is not specified in C++ (see https://en.cppreference.com/w/cpp/language/eval_order). Therefore, it is not possible to gather these function calls in a single expression and guarantee a particular order of evaluation.
> How can I return the accumulated value in one line, without running in some sort of order issue?
Try this:
int a, b, c;
return (a = solve(start, end), b = solve(start, end), c = solve(start, end), a + b + c);
It guarantees the evaluation in order from left to right.
From eval_order:
Every value computation and side effect of the first (left) argument of the built-in comma operator , is sequenced before every value computation and side effect of the second (right) argument.
With persistent states, that code looks like this:
int a = c++ + c++ + c++;
there is no strict ordering about these operations. Partial results may even be cached in different CPU registers and get false result, even if the first c++ increments first, the second and third could be already cached on different CPU-registers for speed optimization, because there are likely multiple adder pipelines in a cpu core that can do it in (instruction-level) parallelism.
Try implementing a chain-calculation API like this:
return solve(s,e).addSolve(e,s).addSolve(s,e).result;
Here, the evaluation has to start from first and end at the last because this is just multiple lines of codes in disguise. Something like this:
class FOO
{
public:
BAR result;
FOO(){ result=0;}
FOO(BAR se){ result=se; }
// assuming solution is s+e
FOO solve(BAR s, BAR e)
{
return FOO(s+e);
}
FOO addSolve(BAR s, Bar e)
{
return FOO(result+s+e);
}
};
Ofcourse the upper example does not save the states in the original object. You need something like this really:
class FOO
{
public:
std::shared_ptr<BAR> result;
// creates original store
FOO()
{
result = std::make_shared<BAR>();
*result=0;
}
// re-uses original
FOO(BAR se, std::shared_ptr<BAR> original)
{
result = original;
*result=se;
}
// assuming solution is s+e
FOO solve(BAR s, BAR e)
{
return FOO(s+e,result);
}
FOO addSolve(BAR s, Bar e)
{
return FOO(*result + s + e,result);
}
};
So that you can still use the original object (the one that was created first) for the result.
Even if original object goes out of scope, the second and the third instances still have the exact same result.
If the initial conditions (parameterless default constructor) meet the requirements of addSolve, then you could simply call same addSolve method 3 times after renaming it to just solve:
// dereferencing explicitly
return *foo.solve(s,e).solve(e,s).solve(s,e).result;
// or implicitly from a method
return foo.solve(s,e).solve(e,s).solve(s,e).getResult();
If you make solve an object that holds the parameters and allows for lazy evaluation, you can overload the + operator for this type to guarantee the order of evaluation:
/**
* object simply stores the parameters for evaluation in operator+
*/
struct solve
{
int m_a;
int m_b;
constexpr solve(int a, int b) noexcept
: m_a(a), m_b(b)
{
}
int operator()() const
{
std::cout << "evaluating solve(" << m_a << ", " << m_b << ")\n";
return m_a + m_b;
}
};
int operator+(solve const& s1, solve const& s2)
{
// do operation of the first operand before the second
auto v1 = s1();
return v1 + s2();
}
int operator+(int s1, solve const& s2)
{
// first operand is already evaluated
return s1 + s2();
}
int main()
{
auto result = solve(1, 2) + solve(3, 4) + solve(5, 6);
std::cout << result << '\n';
return 0;
}
Output:
evaluating solve(1, 2)
evaluating solve(3, 4)
evaluating solve(5, 6)
21
In real code I recommend adding the constexpr modifier to solve::operator()() and the + operators, if possible btw...
Note that this may not be the best idea, since seeing the expression solve(1, 2) + solve(3, 4) + solve(5, 6) it's not obvious, that an order of evaluation is enforced here...
Related
for homework, I need to write a program in cpp with a class composed of an array of pointer to function and operators. I need to create an operator + so as when in the main, this would happen:
int main()
{
int SIZE = 5;
ptrF* arrPtrF = new ptrF[SIZE];
arrPtrF[0] = add;
arrPtrF[1] = sub;
arrPtrF[2] = mult;
arrPtrF[3] = div1;
arrPtrF[4] = pow;
Delegate D1(arrPtrF, SIZE)
cout<< D1[0](6, 7) + D1[0](1, 2)<<endl;
}
the outcome is 15
I am finding difficulty with writing the operator+ ( which in this case need to take take a object parameter)
at first i tried this:
Delegate Delegate:: operator + (const Delegate& b)
{
Delegate tmp;
tmp.m_ptrF[i] = m_ptrF[i] + b.m_ptrF[i];
return tmp;
}
but it gave me an error about the i and b.m_ptrF->initialized i and something about an enum type.
then i tried this:
int Delegate:: operator + (const Delegate& b)
{
int tmp;
int i, x,y;
tmp = m_ptrF[i](x, y) + b.m_ptrF[i](x, y);
return tmp;
}
but it gives me an error->initialized x,y,i knowing that i is index and x,y the parameters of the pointer to function.
what can i do to make it work?
It looks like D1[0](6, 7) is supposed to perform 6 + 7 returning an int and D1[0](1, 2) is supposed to perform 1 + 2 also returning an int. So the addition in D1[0](6, 7) + D1[0](1, 2) is just a regular int addition.
So in other words you are not supposed to be overloading Delegate::operator+ instead you are supposed to writing something like this
XXX Delegate::operator[](int i) const
{
...
}
where XXX is a function like type that will perform the addition on the later parameters.
So XXX will be something like
class XXX
{
public:
int operator()(int x, int y) const
{
...
}
...
};
But XXX will have to perform addition, or substraction or whatever, as appropriate.
So the expression D1[0](6, 7) becomes temp(6,7) where temp is an object of the XXX type above.
At least that's my best interpretation. It's clear that you have misunderstood your requirements.
I'm writing a program for an assignment - it's supposed to be a database
for information about employees in a company. Basically, a vector containing
structures (individual employees).
The trouble I'm having is that remove_if erases everything from the vector - instead of an individual employee.
If I understood documentation/other topics correctly, that function should
do two things - rearrange elements of the vector, and return an
iterator to the first element outside the new range - but it doesn't do
it, it returns an iterator to the first element - and so when the
erase() function is called, all elements are deleted. At least
that's what I found when debugging it.
Here's a mcve of my code:
#include <iostream>
#include <vector>
#include <algorithm>
struct employee {
int number;
};
int main()
{
//creating the vector and adding some values to it
employee one{ 1 };
employee two{ 2 };
employee three{ 3 };
std::vector <employee> staff{ one, two, three };
int m = 2; //some parameter I want to pass to lambda function
auto it = std::remove_if(staff.begin(), staff.end(),
[m](employee a) {
if (a.number == 2)
return true; }
);
staff.erase(it, staff.end());
for (auto it = staff.begin(); it != staff.end(); it++)
std::cout << it->number << std::endl;
system("pause");
return 0;
}
I realise that I could've done the same thing in a loop - in fact, I did, but I just can't wrap my head around why doesn't this approach work. Also, a list would've probably been a better choice for this program (with it, the for loop would have taken fewer instructions to compute), but I've already finished the program, and right now I just really want to know why didn't remove_if work.
Thanks!
EDIT: As #drescherjm pointed out, that was due to the fact that the lambda function didn't return false when the when the if statement wasn't met.
So the question is answered.
The main problem is you are not returning a value when your condition in your lambda is not met. This is undefined behavior not to return a value.
auto it = std::remove_if(staff.begin(), staff.end(),
[m](employee a) {
if (a.number == 2)
return true; }
);
A simple solution is to remove the if and just return the conditional.
auto it = std::remove_if(staff.begin(), staff.end(),
[m](employee a) {
return (a.number == 2);
}
);
However as #killzonekid mentioned this is not correct because you are still not using the parameter.
auto it = std::remove_if(staff.begin(), staff.end(),
[m](employee a) {
return (a.number == m);
}
);
Replacing the fixed 2 with m should take care of that.
I'm working on LLVM and found an interesting piece of code
case ARM::BMOVPCRX_CALL: {
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
.addReg(ARM::LR)
.addReg(ARM::PC)
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
// Add 's' bit operand (always reg0 for this)
.addReg(0));
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
.addReg(ARM::PC)
.addReg(MI->getOperand(0).getReg())
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
// Add 's' bit operand (always reg0 for this)
.addReg(0));
return;
}
My question is about .addReg and .addImm. I wouldn't say I'm new to C++ but I have never seen this type of code. What does it mean and what does it do? Why would anyone want to do something like this?
This pattern of writing software is called 'method chaining' or the 'named parameter idiom'.
For example, you may have a class:
class Example {
int a, b;
public:
Example &a(int const a) {this->a = a; return *this;}
Example &b(int const b) {this->b = b; return *this;}
};
int main(void) {
Example example;
example.a(5).b(6); //example.a is now 5, example.b is now 6
return 0;
}
For this example, it should be noted that there is nothing stopping you from calling example.b(6).a(5) to get an identical result.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Without getting into the general exceptions vs error codes discussion, what do you think are the downsides of using std::pair or std:tuple for returning multiple values, namely the function's return value AND the error/success code, similar to how many Go developers apparently do error handling?
This approach obviously has the advantage of not having to use out parameters for the function return value or error code (depending on which way around you prefer it).
This "idiom" is good because both the type and succes indicator are return values of the function. Failure might not be exceptional, so exceptions are inappropriate sometimes.
The downside however is that you have to split out the two return types. This can be ugly; using std::tie helps but you are unable to construct from multiple return.
bool success;
std::string value;
std::tie(success, value)=try_my_func();
This is quite verbose.
Second, if one of the types is "optional" depending on the value of another element in the tuple then it still has to be constructed which for some types is still very wasteful.
If you are using the idiom a lot, consider instead using something like the boost::optional type. This is close to the haskel maybe than go's multiple return.
Reference
http://www.boost.org/doc/libs/1_52_0/libs/optional/doc/html/index.html
For this purpose, in most cases I use an own wrapper type which introduces some syntactic sugar. Let's see an example:
template <class T>
struct Result
{
public:
enum Status {
Success,
Error
};
// Feel free to change the default behavior... I use implicit
// constructors for type T for syntactic sugar in return statements.
Result(T resultValue) : s(Success), v(resultValue) {}
explicit Result(Status status, std::string errMsg = std::string()) : s(status), v(), errMsg(errMsg) {}
Result() : s(Error), v() {} // Error without message
// Explicit error with message
static Result error(std::string errMsg) { return Result(Error, errMsg); }
// Implicit conversion to type T
operator T() const { return v; }
// Explicit conversion to type T
T value() const { return v; }
Status status() const { return s; }
bool isError() const { return s == Error; }
bool isSuccessful() const { return s == Success; }
std::string errorMessage() const { return errMsg; }
private:
T v;
Status s;
// if you want to provide error messages:
std::string errMsg;
};
Then, simply use this class as the return value in your methods which can return errors:
Result<int> fac(int n) {
if(n < 0)
return Result<int>::error("n has to be greater or equal zero!");
if(n == 0)
return 1;
if(n > 0)
return n * fac(n-1); // gets automatically converted to int
}
Of course this implementation of the factorial function is horrible, but demonstrates the conversion without bothering about the error-extended return type we use.
Example usage:
int main() {
for(int i = -3; i < 4; ++i)
{
Result<int> r = fac(i);
std::cout << i << " | ";
std::cout << (r.isSuccessful() ? "ok" : "error") << " | ";
if(r.isSuccessful())
std::cout << r.value();
else
std::cout << r.errorMessage();
std::cout << std::endl;
}
}
Output:
-3 | error | n has to be greater or equal zero!
-2 | error | n has to be greater or equal zero!
-1 | error | n has to be greater or equal zero!
0 | ok | 1
1 | ok | 1
2 | ok | 2
3 | ok | 6
One big advantage of the custom type is that you can insert some control ensuring that the client code always checks for errors before accessing the actual value and only accesses the value if it was successful respectively the error message if it wasn't. For this, we can extend the class by the following:
struct Result
{
public:
// in all constructors, add:
Result(...) : ..., checked(false) {...}
// in the error checker methods, add: (and drop const-ness)
bool is...() { checked = true; return ... }
// rewrite the value conversion as follows:
operator T() const { std::assert(checked && isSuccessful()); return v; }
T value() const { std::assert(checked && isSuccessful()); return v; }
// rewrite the errorMessage-getter as follows:
std::string errorMessage() const { std::assert(checked && isError()); return errMsg; }
private:
...
bool checked;
};
You might want to make the class definition depending on the build mode (debug build / release build).
Note that the example has to be rewritten as follows:
Result<int> fac(int n) {
if(n < 0)
return Result<int>::error("n has to be greater or equal zero!");
if(n == 0)
return 1;
if(n > 0) {
Result<int> r = fac(n - 1);
if(r.isError()) return r; // propagate error (similar to exceptions)
return n * r; // r gets automatically converted to int
}
}
The main-code from above is still valid, as it already did error-checking before accessing the value / the error message.
“what do you think are the downsides of using std::pair or std:tuple for returning multiple values, namely the function's return value AND the error/success code”
The main downside of that simplistic (C level) approach to failure handling is a
loss of safety.
I.e. there's more that can go wrong, such as accessing an indeterminate result value. Or just using a return value when the function didn't produce a meaningful one.
The old Barton & Nackman Fallow class solved this safety problem by restricting access to the result value. Essentially the calling code has to check if there is a result value, before using it, and using a logically non-existent result value causes an exception or termination. The boost::optional class does much the same.
If you don't want a dependency on Boost, then an Optional class is trivial to implement for POD result type, and at a cost of a little possible inefficiency (dynamic allocation) you can just use a std::vector to carry a non-POD possible result.
The challenge is to retain the clarity of the calling code, which is the whole point of the exercise…
It's better than regular error codes because you don't have to waste your life with out parameters. But it still retains all of the very serious downsides.
Really, it's just a micro change, it's still error codes- there's no significant benefit.
Below are two common issues resulting in undefined behavior due to the sequence point rules:
a[i] = i++; //has a read and write between sequence points
i = i++; //2 writes between sequence points
What are other things you have encountered with respect to sequence points?
It is really difficult to find out these issues when the compiler is not able to warn us.
A variation of Dario's example is this:
void Foo(shared_ptr<Bar> a, shared_ptr<Bar> b){ ... }
int main() {
Foo(shared_ptr<Bar>(new Bar), shared_ptr<Bar>(new Bar));
}
which might leak memory. There is no sequence point between the evaluation of the two parameters, so not only may the second argument be evaluated before the first, but both Bar objects may also be created before any of the shared_ptr's
That is, instead of being evaluated as
Bar* b0 = new Bar();
arg0 = shared_ptr<Bar>(b0);
Bar* b1 = new Bar();
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
(which would be safe, because if b0 gets successfully allocated, it gets immediately wrapped in a shared_ptr), it may be evaluated as:
Bar* b0 = new Bar();
Bar* b1 = new Bar();
arg0 = shared_ptr<Bar>(b0);
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
which means that if b0 gets allocated successfully, and b1 throws an exception, then b0 will never be deleted.
There are some ambigous cases concerning the order of execution in parameter lists or e.g. additions.
#include <iostream>
using namespace std;
int a() {
cout << "Eval a" << endl;
return 1;
}
int b() {
cout << "Eval b" << endl;
return 2;
}
int plus(int x, int y) {
return x + y;
}
int main() {
int x = a() + b();
int res = plus(a(), b());
return 0;
}
Is a() or b() executed first? ;-)
Here is a simple rule from Programming principles and practices using c++ by Bjarne Stroustup
"if you change the value of a variable in an expression.Don't read or
write twice in the same expression"
a[i] = i++; //i's value is changed once but read twice
i = i++; //i's value is changed once but written twice
An example similar to Dario's, which I've also seen people fall into:
printf("%s %s\n", inet_ntoa(&addr1), inet_ntoa(&addr2));
Not only will this either print "addr1 addr1" or "addr2 addr2" (because inet_ntoa returns a pointer to a static buffer overwritten by further calls), but also it is not defined which of these will be the case (because C does not specify order of evaluation in argument lists).
Here are two good expressions that work for most C compilers, yet are ambiguous due to sequence points:
x ^= y ^= x ^= y; // in-place swap of two variables
And also
int i=0;
printf("%d %d %d", ++i, ++i, ++i); // usually prints out 3 2 1... but not for all compilers!
The one I've seen recently was due to programmer's desire to save on class formatting time, completely wrong-headed:
class A
{
public:
...
const char* Format( const string& f ) const
{
fmt = Print( f, value );
return fmt.c_str();
}
operator const char* () const { return fmt.c_str(); }
private:
struct timeval value;
mutable string fmt;
};
A a( ... );
printf( "%s %s\n", a.Format( x ), a.Format( y );
The last line would either always print the same value for both formats (or crash the program since internal string would release the returned memory).
Another one is from some interview I had long ago:
void func( int x, int y, int z )
{
printf( "%d %d %d\n", x, y, z );
}
...
int i = 0;
func( i, ++i, i++ ); /* don't do this in real software :) */