assume this following function:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
return 1 + max(findHeight(n->left), findHeight(n->right));
}
}
Pretty standard recursive treeHeight function for a given binary search tree binaryTree. Now, I was helping a friend (he's taking an algorithms course), and I ran into some weird issue with this function that I couldn't 100% explain to him.
With max being defined as max(a,b) ((a)>(b)?(a):(b)) (which happens to be the max definition in windef.h), the recursive function freaks out (it runs something like n^n times where n is the tree height). This obviously makes checking the height of a tree with 3000 elements take very, very long.
However, if max is defined via templating, like std does it, everything is okay. So using std::max fixed his problem. I just want to know why.
Also, why does the countLeaves function work fine, using the same programmatic recursion?
int binaryTree::countLeaves(node *n) {
if (n == NULL) {
return 0;
} else if (n->left == NULL && n->right == NULL) {
return 1;
} else {
return countLeaves(n->left) + countLeaves(n->right);
}
}
Is it because in returning the ternary function, the values a => countLeaves(n->left) and b => countLeaves(n->right) were recursively double called simply because they were the resultants?
Thank you!
The question was answered below
I just wanted to link some literature on the subject for future reference:
http://www.boostpro.com/tmpbook/preprocessor.html
http://msdn.microsoft.com/en-us/library/z3f89ch8.aspx
The main difference between the two implementations being:
#define max(i, j) (((i) > (j)) ? (i) : (j))
vs
template<class T> T max (T i, T j) { return ((i > j) ? i : j) }
Thank you all!
Macros are expanded by the preprocessor, before the compiler gets to see the code. This means that, for example, macro parameters might be evaluated more than once.
With your macro, you're going to end up with something akin to:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
return 1 + (findHeight(n->left) > findHeight(n->right)) ? // call once...
findHeight(n->left) : findHeight(n->right); // and ouch
}
}
As you can see, it's going to evaluate both functions, then one more an additional time. This is why macros can be evil.
You can disable the macro by defining NOMINMAX prior to including the Windows headers. Then use the function in <algorithm> instead.
If he must use the macro, he'll have to store the calculations in a variable:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
const int leftHeight = findHeight(n->left);
const int rightHeight = findHeight(n->right);
return 1 + max(leftHeight, rightHeight);
}
}
With a function, each call will be evaluated prior to calling the function. That is, it's somewhat like the previous code block. It evaluates the function's arguments, gets the results, then passes those into the std::max function. There are no repeated evaluations.
That max macro evaluates the arguments twice - and since your argument is a recursive function call, that's probably the source of the perf problem.
It's because of the definition of max. You're making 3 calls to findHeight() instead of 2.
a better option would be to declare a function with following signature:
int max(int, int)
This will prevent the recursive expansion of macro.
Related
This is part of a debugging assignment that I've been stuck on for days. I'm not as much looking for an answer as much as I'm looking for where to look to find the answer.
I have a function that takes an int as a parameter, and the test uses that function to calculate the sum of the range (0,n]. My problem is that I am new to C++ and have exhausted my knowledge of where to look to solve this. Any help would be greatly appreciated.
Also, it goes without saying that I cannot modify the test file.
Header.h
bool getNum(int n);
Header.cpp:
bool getNum(int n)
{
n = n + 1;
if (n < 10)
{
return true;
}
else
{
return false;
}
}
Test.cpp
int n = 0;
int sum = 0;
while (getNum(n) && n)
{
sum += n;
}
CHECK(sum == 45);
My problem is that I have no way of getting n to be true to pass the logical &&, so the test never visits the inside of the while loop.
You can change the value of an argument to a function, by taking that argument as a reference:
bool getNum(int &n) // note the reference parameter
{
// changes to n are visible to the caller of this function
}
You have to change the declaration of getNum to match as well, of course.
Note that there is no change to the calling code.
Here's a demo of a working example.
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
Looking to achieve a sort of dynamic expression where I can later evaluate the booleans if called.
condition &&= condition2; //not evaluated just yet
condition ||= condition3;
if (condition) //evaluated now
do this;
else
do this;
for example I am the using the same conditions throughout my code and it would be easier if I could just adjust the one statement or add more to it even when the programs running.
conditions = (x>50 && y>200) && (type == MONKEY);
conditions &&= (x<75 && y<250);
and later on in the code
if (conditions)
cout<<"Hello!";
edit: The conditions should be evaluated at the if statement.
Be very careful when working with && and &
Reason 1
Expanding the postulated (and syntactically invalid)
condition &&= condition2;
to
condition = condition && condition2;
reveals a subtlety: condition2 will not be evaluated if condition is false.
Reason 2
& and && also have differing behaviour for integral types, e.g. 0b01 & 0b10 is 0 but 0b01 && 0b10 is true (here I'm using C++14 binary literals).
Conclusion
So I'd favour the compaction
if (condition = condition && condition2){
// do this
} else {
// do this
}
where condition2 is only evaluated if condition is true
The sensible solution here is to create named functions for those conditions and call them whenever necessary.
That said ...
Is it possible [..]
Of course. To defer evaluation, just wrap your conditions in (lambda) functions. Proof of concept:
#include <functional>
#include <iostream>
template<typename F, typename G>
auto and_also (F f, G g) {
return [=]() {
bool first = f();
if (! first) return false;
return static_cast<bool>(g());
};
}
int main () {
int dummy = -1;
std::function<bool()> condition = [&](){return dummy > 0;};
condition = and_also(condition, [&](){return dummy < 42;});
dummy = 21;
if (condition()) std::cout << "in range" << std::endl;
}
In order to address the use case, you've mentioned in a comment:
Example: moving through pixels in a window and avoiding certain areas of the window.
For reasons of readability, I'd recommend you define a function, e.g., like this (pseudocode) example:
bool is_in_rect(point2i p, rect2i rect) {
// check x range
if (p.x >= rect.x1 && p.x < rect.x2)
return true;
// check y range
if (p.y >= rect.y1 && p.y < rect.y2)
return true;
return false;
}
You can add functions for specialized situations as you wish:
bool is_in_monkey_rect(point2i p, rect2i rect) {
return rect.type == MONKEY && is_in_rect(p, rect);
}
But overall I'm just interested to see if this is possible.
Other than delegating to a function, you'd probably use macros to simulate this kind of lazy evaluation. But I wouldn't recommend that.
Note that, depending on the actual nature of the problem, it might make more sense to adapt the iteration pattern, rather than iterating all the data and check every single pixel for relevance.
A common way to do something in one place, so you don't repeat yourself everywhere is to make a function.
For example,
bool special_condition(bool current_condition, int x)
{
return current_condition && (x<75 && y<250);
}
allows this whenever needed.
if (special_condition(conditions))
do_something();
else
do_something_else();
This will be evaulated when the if is encountered, however, this won't short circuit if current_condition is false when the function will still be called.
Short answer Stefan, in C++ no.
The expression is evaluated during &=.
Short circuiting expressions e.g. ignoring b if a is false in expressions such as a && b, is usually configurable in your environment and normally on.
If you still wish to do so, create an evaluation function instead.
/Anders
Is there any general way to refer to the current function being executed? Something that would let me do this for example,
([] (int n) -> int {
if (n <= 1) {
return 1;
}
return n * thisFunc(n - 1);
})()
Mainly, I'm thinking of anonymous functions calling themselves without the use of auxiliary named functions. So avoiding this.
You can use a function pointer, or function object in C++11, but there is no built-in way to refer to a function. For example:
std::function<int (int)> myFun = [] (int i)
{
if i <= 1
{
return 1;
}
return i * myFun(i-1);
}
I would argue that calling a lambda recursively is not how they were meant to be used. Lambdas are essentially meant to provide inline functionality and thus are meant to be fairly simple.
Not to mention that the example you give can very easily be replaced with a loop thus resulting in much more efficient implementation:
int result = 1;
while (i > 1)
{
result = result * i;
i--;
}
I have some C code where I need to do some calculations with an array of data. The data can be either INT or DOUBLE. In order to deal with the different data types, I was thinking of using an if / else statement and define the pointer holding the data inside that statement:
/* put values into M, depending on data type*/
if (data_type == 2)
{
double *M;
M = somefunction(DOUBLE);
} else {
unsigned int *M;
M = somefunction(UINT16);
}
/* dummy code - usually I do some calculations on M which are data type independent */
for (i=0;i<(10);i++) {
M[i]=0;
}
This leads to scoping problems because M is not defined outside the if / else construct:
error: ‘M’ undeclared (first use in this function)
If I move the definition of M outside the if / else statement, the code will compile but M inside the if / else is a different M outside.
So I can circumvent the problem by defining two pointers, one double and one int and check everywhere in my code which type I'm dealing with:
double *Mdouble;
unsigned int *Mint;
/* put values into M, depending on data type*/
if (data_type == 2)
{
Mdouble = somefunction(DOUBLE);
} else {
Mint = somefunction(UINT16);
}
/* dummy code - usually I do some calculations on M which are data type independent */
for (i=0;i<(10);i++) {
if (data_type == 2) {
Mdouble[i]=0;
} else {
Mint[i]=0;
}
}
So here's my question:
How can I solve this problem where M is a double or int, depending on my incoming data? Could I solve this with some kind of pointer to a pointer work around? I don't want to write duplicate code for each case.
EDIT could template functions or overloading of functions solve my problem? I'm flexible regarding a C / C++ specific solution
You're going to have to write duplicate code.
At the base level, the required machine code for adding two numbers is different for integers vs floating-point numbers.
This difference is "hidden" since data is typed, so the compiler always knows the type of each operand and can generate the proper code.
If you want to move that information until run-time, the compiler can no longer do its thing, so you're going to have to do it instead and make sure your code takes the proper path.
You can try to use an C union:
#include <string.h>
#include <stdio.h>
int main(int argc, char** argv) {
union MyUnion {
int I;
double D;
};
union MyUnion M[10];
// Initializing the array to 0 (data type independent)
memset(M, 0, 10*sizeof(MyUnion));
M[0].I = 1;
M[1].D = 1.5;
if (argc==1) { // It should be "if (data_type==2) {"
// but I wanted an example that compiles easily
printf("%i\n", M[0].I); //somefunction(M[0].I);
} else {
printf("%lf\n", M[1].D); //somefunction(M[1].D);
}
}
In C you will have to use a macro
int8_t* ptr=...;
while(n)
{
switch(data_type)
{
case TYPE_DOUBLE:
A_MACRO_THAT_DEFINES_YOUR_OPERATION((double*)ptr);
ptr+=sizeof(double);
break;
case TYPE_INT:
A_MACRO_THAT_DEFINES_YOUR_OPERATION((int*)ptr);
ptr+=sizeof(int);
break;
}
--n;
}
This solution is slow since it needs to test the data type for each element. You can instead write the entire loop as a macro. This will be faster but harder to read.
If you can use C++, use a template instead. Here is a solution using templates:
template<class T>
void doStuff(T* ptr_begin,T* end)
{
while(ptr_begin!=ptr_end)
{
// Do stuff
++ptr_begin;
}
}
void doStuffWrapper(void* ptr_begin,void* ptr_end,uint32_t type)
{
switch(type)
{
case TYPE_DOUBLE:
doStuff((double*)ptr_begin,(double*)ptr_end);
break;
case TYPE_INT:
doStuff((int*)ptr_begin,(int*)ptr_end);
break;
}
}
As a side note: I prefer switch-case over if-else in this case since it is easier to maintain, and may produce faster code.
You can use a macro, e.g.:
#define CALCULATIONS(M) do { \
for (i=0;i<(10);i++) \
(M)[i]=0; \
} while (0)
and then in your other code:
if ( data_type == 2 )
{
double *M = whatever;
CALCULATIONS(M);
}
See here if you are unfamiliar with the do...while(0) technique
It sounds like you want a templatized function.
But I think the question comes down to, can you put all your work in the function?
template <typename T>
T* somefunction(T data){
//start old somefunction code
T* result = new T[10]{data, data, data, data, data, data, data, data, data, data};
//end old somefunction code
//begin "calculations on M which are data type independent"
for(int i = 0; i < 10; i++){
M[i] = 0;
}
return M;
}
So with the above code you could do either double* Mdouble = somefunction(13.13) or short* Mshort = somefunction(13);
The best case scenario is in which M was really a throw away array anyway, in which case you could even allocate the data in the template function's stack frame and avoid using new.