Let's say we have a simple recursion like.
int x(int a){
if(a<10)
x(a+1);
else
!STOP!
b++;
return b;
}
Globaly:
int b=0;
In main we could have something like this:
int p=x(1);
Is there any way to stop the recursion so that the p will be 0, this means that "b++" will never be executed.
I'll be grateful if you could tell me some expresion to put instead of the !STOP!
But, I don't want anything like this, I just want to stop the recursion, like break; does in a while() loop...:
int ok=0;
int x(int a){
if(a<10)
x(a+1);
else
ok=1;
if(ok==0)
b++;
return b;
}
If there's anything unclear about the question, just ask.
Why wouldn't you do this?
int x(int a){
if(a<10) {
x(a+1);
b++;
}
return b;
}
The thing is, though, you're modifying a global in a recursive routine, which is not especially threadsafe and pretty sloppy. You're returning a value that is always ignored except by the top level caller. You're also doing something that is better off being done in a loop (but I assume that your actual case is bigger than this, or you're a student).
You can't really "break" the recursion - returning unwinds well enough. In oldey-timey C you might use setjmp/longjmp (and all its perils - in other words, DON'T), and in C++ you might use try/catch/throw, which will unwind the stack as well.
How about like this?
int x(int a){
if(a>0 && a<10)
x(a+1);
b++;
return b;
}
The only thing in C++ that will unwind the stack like that is an exception. There's also setjmp()/longjmp(), but those should never be used in a C++ program. Any other construct can at most return from the current function.
How about returning?
int x(int a){
if(a<10)
x(a+1);
else
return b;
b++;
return b;
}
I think this looks a bit better
int x(int a){
if(a<10)
x(a+1);
else
return b;
return ++b;
}
EDIT:
I think You could use exception mechanism to unwind the stack and get to the point of first invocation, but it's safe after entering main(). Referencing b in x, given the code:
int b = 0;
int p = x(1);
suggests that x is used for initialization of some global variable and may be executed before main(). How about using some helper function that wraps invocation of x in a try - catch block and throwing an exception in the place of |STOP|?
If you're trying to declare b in main(), and use b in x() then there's something wrong already to begin with. Instead, make b into a local variable by passing it as a parameter to x, and returning a modified version of b.
int x(int a, int b){
if(a<10)
return x(a+1,b+1);
else
return b;
}
I'm not a big fan of using an Exception for control. I don't expect you'll save many cycles by using Exceptions instead of if/return statements. You're going to have to test your boundary conditions anyway before throwing an Exception.
You can however simplify the problem a bit by changing the return type of the function.
bool x(int a){
if(ok) //Exit early before next call up?
return true;
if(a<10){
if(x(a+1)) //Have we been told to exit early?
return true; //Yes
b++; //Do some work
if(ok) //Exit early in the next call down?
return true;
}
return false; //Normal Exit
}
Related
In some cases it happens for me to declare a variable without knowing its value first like:
int a;
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
}
do_something_with(a);
Is it the standard professional practice to assign some clearly wrong value like -1000 anyway (making potential bugs more reproducible) or it is preferred not to add the code that does nothing useful as long as there are no bugs? From one side, looks reasonable to remove randomness, from the other side, magical and even "clearly wrong" numbers somehow do not look attractive.
In many cases it is possible to declare when the value is first known, or use a ternary operator, but here we would need it nested so also rather clumsy.
Declaring inside the block would move the variable out of the scope prematurely.
Or would this case justify the usage of std::optional<int> a and assert(a) later, making sure we have the value?
EDIT: The bugs I am talking about would occur if suddenly all 3 conditions are false that should "absolutely never happen".
As far as I know the most popular and safest way is using inline lambda call. Note that the if should be exhaustive (I added SOME_DEFAULT_VALUE as a placeholder). I suppose that if you don't know what to put in final else block you should consider a few options:
using optional and putting none in the else,
throwing exception that describes the problem,
putting assert if logically this situation should never happen
const int a = [&] {
if (c1) {
return 1;
} else if (c2) {
return 2;
} else if (c3) {
return -3;
} else {
return SOME_DEFAULT_VALUE;
}
}();
do_something_with(a);
In a situation when the initialization logic duplicates somewhere you can simply extract the lambda to a named function as other answers suggest
In my opinion, the safest option, if you dont want this other value (its just useless), then it may lead to really subtle bug which may be hard to find. Therefore I would throw an expectation when any of the conditions is not met:
int get_init_value(bool c1, bool c2, bool c3) {
if (c1) { return 1; }
else if (c2) { return 2; }
else if (c3) { return -3; }
throw std::logic_error("noone of conditions to define value was met");
}
That way we avoid getting some weird values that want actually match our code, but they would compile anyways ( debugging it may take a lot of time). I consider it way better than just assigning it some clearly wrong value.
Opinion based answer!
I know the example is a simplification of a real, more complex example, but IMHO it seems nowadays this kind of design issue emerge more often, and people sometimes kinda tend to over-complicate it.
Isn't it the whole purpose of a variable to hold some value? Thus isn't having a default value for this variable also a feasible thing?
So what exactly is wrong with:
int a = -1000; // or some other value meant to used for undefined
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
}
do_something_with(a);
It is simple and readable... No lambdas, exceptions and other stuff making the code unnecessary complicated...
Or like:
int a;
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
} else {
a = -1000; // default for unkown state
}
do_something_with(a);
You could introduce a constant const int undefined = -1000; and use the constant.
Or an enum if c1, c2, c3 are states in some sort (which it most likely is)...
You could rearrange the code to eliminate the variable if it is not needed elsewhere.
if (c1) {
do_something_with(1);
} else if (c2) {
do_something_with(2);
} else if (c3) {
do_something_with(-3);
}
I would introduce a default value. I'm usually using MAX value of the type for this.
Shortest you can do this with the ternary operator like this:
#include <climits>
int a = c1 ? 1 : c2 ? 2 : c3 ? -3 : INT_MAX;
do_something_with(a);
I understand your real code is much more complicated than the outline presented, but IMHO the main problem here is
should we do_something_with(a) at all if a is undefined,
rather than
what the initial value should be.
And the solution might be adding explicitly some status flag like a_is_defined to the actual parameter a instead of using magic constans.
int a = 0;
bool a_is_defined = false;
When you set them both according to c... conditions and pass them to do_something() you'll be able to make a clear distinction between a specific if(a_is_defined) {...} path and a default (error handling?) else {...}.
Or even provide separate routines to explicitly handle both paths one level earlier: if(a_is_defined) do_someting_with(a); else do_something_else();.
I am facing a situation where i need cppchecks to pass but it gets tricky sometimes. What do you generally do in such circumstances ?
For example.
#include<iostream>
using namespace std;
void fun1();
int fun2();
int main()
{
fun1();
}
void fun1()
{
int retVal;
if (-1 == (retVal = fun2()))
{
cout <<"Failure. fun2 returned a -1"<< endl;
}
}
int fun2()
{
return -1;
}
We usually see code such as the above. cppcheck for the above file would give an output as below -
cppcheck --suppress=redundantAssignment
--enable='warning,style,performance,portability' --inline-suppr --language='c++' retval_neverused.cpp Checking retval_neverused.cpp... [retval_neverused.cpp:13]: (style) Variable 'retVal' is assigned a
value that is never used.
I don't want to add some dummy line printing retVal just for the sake of cppcheck. Infact it can be a situation where I throw an exception and I don't want the exception to have something trivial as the value of retVal in it.
CppCheck is kinda right though. You don't need retVal at all. just check the return value of fun2 directly: if( -1 == fun2() )
As an aside, assigning variables inside conditional expressions is really bad practice. It makes it a lot harder to catch typos where you meant to type == but actually typed =.
You could rewrite as:
const int retval = fun2();
if (retval == -1)
This technique is, IMHO, easier to debug because you can see, with a debugger, the value returned from fun2 before the if statement is executed.
Debugging with the function call in the if expression is a little more complicated to see the return value from the function.
One common way is with something like this:
#define OK_UNUSED(x) (void)x
void fun1()
{
int retVal;
if (-1 == (retVal = fun2()))
{
OK_UNUSED (retVal);
cout <<"Failure. fun2 returned a -1"<< endl;
}
}
This indicates to humans that retVal is intentionally unused and makes CppCheck think it's used, suppressing the warning.
Note that this macro should not be used if evaluating its parameter has consequences. In that case, you need something fancier like:
#define OK_UNUSED(x) if(false && (x)) ; else (void) 0
int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
if(k==n1)
return count;
if(k>n1)
return --count;
}
This is a function that returns the largest power of two less than n. When I run it in my ubuntu terminal (g++ 4.8.4), it works fine. But when I am running it on www.hackerrank.com, it gives an error(control reaches end of non void function). The problem is, I participate in many contests on this website and I have come across this problem multiple times.
Please tell if you know how I can fix it.
You can use else if statement like this:
int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
else if(k==n1)
return count;
else // Eliminate compiler errors (warnings)
return --count;
}
or as said #juanchopanza:
int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
if(k==n1)
return count;
// Eliminate compiler errors (warnings)
return --count;
}
It will do the same thing as your code, but will not give a doubt to compiler that can be no return points from function.
'control reaches end of non void function' is a warning not an error, it's safe to ignore in this case but if you want to suppress the warning there are multiple ways:
put a return after the last condition
as Mykola suggested restructure the conditions to be explicit
set the -Wno-return-type flag
I have read in Scott Meyers' Effective C++ book that:
When you inline a function you may enable the compiler to perform context specific optimizations on the body of function. Such optimization would be impossible for normal function calls.
Now the question is: what is context specific optimization and why it is necessary?
I don't think "context specific optimization" is a defined term, but I think it basically means the compiler can analyse the call site and the code around it and use this information to optimise the function.
Here's an example. It's contrived, of course, but it should demonstrate the idea:
Function:
int foo(int i)
{
if (i < 0) throw std::invalid_argument("");
return -i;
}
Call site:
int bar()
{
int i = 5;
return foo(i);
}
If foo is compiled separately, it must contain a comparison and exception-throwing code. If it's inlined in bar, the compiler sees this code:
int bar()
{
int i = 5;
if (i < 0) throw std::invalid_argument("");
return -i;
}
Any sane optimiser will evaluate this as
int bar()
{
return -5;
}
If the compile choose to inline a function, it will replace a function call to this function by the body of the function. It now has more code to optimize inside the caller function body. Therefore, it often leads to better code.
Imagine that:
bool callee(bool a){
if(a) return false;
else return true;
}
void caller(){
if(callee(true)){
//Do something
}
//Do something
}
Once inlined, the code will be like this (approximatively):
void caller(){
bool a = true;
bool ret;
if(a) ret = false;
else ret = true;
if(ret){
//Do something
}
//Do something
}
Which may be optimized further too:
void caller(){
if(false){
//Do something
}
//Do something
}
And then to:
void caller(){
//Do something
}
The function is now much smaller and you don't have the cost of the function call and especially (regarding the question) the cost of branching.
Say the function is
void fun( bool b) { if(b) do_sth1(); else do_sth2(); }
and it is called in the context with pre-defined false parameter
bool param = false;
...
fun( param);
then the compiler may reduce the function body to
...
do_sth2();
I don't think that context specific optimization means something specific and you probably can't find exact definition.
Nice example would be classical getter for some class attributes, without inlining it program has to:
jump to getter body
move value to registry (eax on x86 under windows with default Visual studio settings)
jump back to callee
move value from eax to local variable
While using inlining can skip almost all the work and move value directly to local variable.
Optimizations strictly depend on compiler but lot of think can happen (variable allocation may be skipped, code may get reorder and so on... But you always save call/jump which is expensive instruction.
More reading on optimisation here.
This question already has answers here:
Returning a reference to a local variable in C++
(3 answers)
Closed 8 years ago.
I'm trying to understand why the second piece of code compiles fine, given that the first doesn't.
int & test(void) {
int v = 0;
return v;
}
int main(void){
int & r = test();
return 0;
}
I understand that this doesn't work because you can't pass a reference to an automatic variable that will be deleted. It seems to me that the code below should have the same problem but it doesn't.
int & test1(int & x) {
return x;
}
int & test2(void) {
int x = 0;
return test1(x);
}
int main(void){
int & r = test2();
return 0;
}
Seems like the intermediate function is solving the problem. But why?
Just because something compiles, doesn't mean it works...
The two "alternatives" both suffer from the same exact problem; r, in main, is a dangling reference, what it refers to is long gone, and using it will lead to undefined behavior.
1st snippet
In the first example it's easy enough for the compiler to see that you are returning a reference to a local variable, which (as compilers know) doesn't make any sense.. the referred to instance will be dead when the reference reach main.
The compiler is being a good champ and tells you about the issue.
2nd snippet
In the second example you are doing the same thing, but adding a redirection in-between. A compiler got many tricks up its sleeve, but back-tracing every possible execution path to see if a developer is returning a reference to a local variable, by indirection, isn't one of them.
The compiler can't see that you are being bad, and it cannot warn you about issues it doesn't know about.
Conclusion
Returning a reference to a local variable is bad, no matter how you do it.
Think about what the compiler would have to do to catch the problem you're demonstrating. It would have to look at all callers of test1 to see whether they're passing it a local. Perhaps easy enough, but what if you insert more and more intermediate functions?
int & test1(int & x) {
return x;
}
int & test2(int & x) {
return test1(x);
}
int & test3() {
int x = 0;
return test2(x);
}
int main(void){
int & r = test3();
return r;
}
The compiler would have to look not only at all callers of test1, but then also all callers of test2. It would also have to work through test2 (imagine that it's more complex than the example here) to see whether it's passing any of its own locals to test1. Extrapolate that to a truly complex piece of code--keeping track of that sort of thing would be prohibitively complex. The compiler can only do so much to protect us from ourselves.
The both code examples are ill-formed and have undefined behaviour because local objects will be deleted after exiting the functions. So the references will be invalid.
To understand that the second example does not differ from the first example you could rewrite it the following way (insetad of calling the second function)
/*
int & test1(int & x) {
return x;
}
*/
int & test2(void) {
int x = 0;
/* return test1(x);*/
int &r = x;
return r;
}
As you see there is no any difference between the examples.
To achieve what you want you could the following way
int test()
{
int v = 0;
return v;
}
int main()
{
const int & r = test();
return 0;
}