Why does min() works in Xcode, but not max ()? - c++

I am writing a C++ program using Xcode, and I need to find the max and min of two numbers. I decided to use the built-in max and min functions of C++.
When I do :
float result = min(x1,x2); // x1, x2 are floats
Xcode recognises min just fine.
But when I do:
float result = max(x1,x2); // x1, x2 are floats
Xcode complains with the error:
No matching function for call to 'max'
If I COMMAND + Click on either max or min, the Xcode quickly takes me to the function definitions, so clearly Xcode knows they are both there.
How do I get max to work ?
EDIT: I have tried calling std::max, but I get the same error.

This type of error occur generally when your parameters that you are passing to min or max function is not of same type.
Make sure to check the parameter type of both parameters.

Related

Error: ambiguous call to overloaded function

float App::fresnelReflectTerm(float etaPos, float etaNeg, float cos_theta_i)
{
float theta_i;
theta_i = acos(cos_theta_i);
...
This generates an "ambiguous call to overloaded function error" and says that there are four options:
float acos(float fValue)
double acos(double _X)
float acos(float _X)
long double acos(long double _X)
I suspect that the problem is that the first and third both take a float arg and return a float value. But can anyone give me a hint about how I might determine (I'm using Visual Studio) where those four functions came from, so that I can eliminate the duplication, for instance? Or perhaps just give me a hint on how to get around this problem.
You can press F12 on that function.
Update
Based on comments from the OP, the problem was due to a definition of acos being brought in from G3D::. Using std::acos as opposed to acos will remove the ambiguity.
You can enable the file listing compiler option in VS studio, so you will know which files are include during compiling, see this msdn article.

Variable declaration as side-effect

So I'm looking over C++ operator rules as I do when my programs start behaving wonkily. And I come across the comma operator. Now, I have known it was there for a while but never used it, so I began reading, and I come across this little gem:
if (int y = f(x), y > x)
{
// statements that use y
}
I had never thought about using commas' first arguments' side-effects to get locally-scoped variables without the need for bulky block-delimited code or repeated function calls. Naturally, this all excited me greatly, and I immediately ran off to try it.
test_comma.cpp: In function 'int main()':
test_comma.cpp:9:18: error: expected ')' before ',' token
if (int y = f(x), y > x) {
I tried this on both a C and C++ compiler, and neither of them liked it. I tried instead declaring y in the outer scope, and it compiled and ran just fine without the int in the if condition, but that defeats the purpose of the comma here. Is this just a GCC implementation quirk? The opinion of the Internet seems to be that this should be perfectly valid C (and ostensibly, to my eye, C++) code; there is no mention of this error on any GCC or C++ forum that I've seen.
EDIT: Some more information. I am using MinGW GCC 4.8.1-4 on Windows 7 64-bit (though obviously my binaries are 32-bit; I need to install mingw-w64 one of these days).
I also tried using this trick outside of a conditional statement, as below:
int y = (int z = 5, z);
This threw up two different errors:
test_comma.cpp: In function 'int main()':
test_comma.cpp:9:11: error: expected primary-expression before 'int'
int y = (int z = 5, z);
^
test_comma.cpp:9:11: error: expected ')' before 'int'
With creative use of parentheses in my if statement above, I managed to get the same errors there, too.
Contrary to what several other people have claimed, declarations inside the if conditional are perfectly valid. However, your code is not.
The first problem is that you're not actually using the comma operator, but [almost] attempting to declare multiple variables. That is not valid in an if conditional. And, even if it were possible, your second declaration would be entirely broken anyway since you try to redeclare y, and you do so with > instead of =. It all simply makes no sense.
The following code is sort of similar:
if (int y = (f(x), y > x))
Now at least it's half-valid, but you're using y uninitialised and yielding undefined behaviour.
Declarations and expressions are not the same thing, so the following is quite different code:
int y = 0;
if (y = f(x), y > x)
Now you don't have a problem with uninitialised variables, either (because I initialised y myself), and you're getting this "side-effect declaration" that doesn't change the resulting value of the if conditional. But it's about as clear as mud. Look how the precedence forms:
int y = 0;
if ((y = f(x)), (y > x))
That's not really very intuitive.
Hopefully this total catastrophe has been a lesson in avoiding this sort of cryptic code in entirety. :)
You cannot declare variable and apply operator , simultaneously either you are declaring variable (in case of if it would be only one 'cause result needs to be resolved to bool), either you are writing some statement (also resolving to bool) which may include operator , in it.
You need to declare y on the top of if condition:
int y;
if(y=f(x),y>x)
{
}
This will check the last condition defined in the if condition and rest others are executed as general statements.

using clamp function in OpenCL code

In my OpenCL code (which is not coded by myself, it's just an example code from internet), there is the following sentence to use the function of clamp.
return clamp(color,0,1);
However it seems that this makes error during compilation, so I got the error info message by using CL_PROGRAM_BUILD_LOG from clGetProgramBuildInfo.
Error during compilation! (-11)
4483
build log
:211:9: error: call to 'clamp' is ambiguous
return clamp(color,0,1);
^~~~~
<built-in>:3558:26: note: candidate function
float4 __OVERLOADABLE__ clamp(float4 x, float min, float max) ;
^
<built-in>:3577:25: note: candidate function
float4 __OVERLOADABLE__ clamp(float4, float4, float4);
^
<built-in>:3556:26: note: candidate function
float3 __OVERLOADABLE__ clamp(float3 x, float min, float max) ;
^
<built-in>:3575:25: note: candidate function
float3 __OVERLOADABLE__ clamp(float3, float3, float3);
^
:296:52: error: address expression must be an lvalue or a function designator
r.origin = matrixVectorMultiply(viewTransform, &(float3)(0, 0, -1));
^~~~~~~~~~~~~~~~~~
:297:62: error: address expression must be an lvalue or a function designator
r.dir = normalize(matrixVectorMultiply(viewTransform, &(float3)(x, y, 0)) - r.origin);
^~~~~~~~~~~~~~~~~
Is there any necessary keyword for using clamp function in OpenCL code? BTW, I'm using the environment of the Linux Ubuntu 10.04 64bit.
Try the following
return clamp(color,0.0f,1.0f);
This way we know for sure that 2nd and 3rd params are not ambiguous and that you are trying to call the function:
clamp(float4 color, float min, float max);
If this doesn't work, then see your color param, but the 2nd and 3rd param should be fine now.
There are several overloaded clamp builtin functions in OpenCL; the compiler needs to select exactly one, based on the types of the arguments. Valid combinations are
T clamp(T,T,T) and T clamp(T,S,S)
where T is one of the OpenCL integral or floating point types, and S is the scalar type of an element of T when T is a vector type.
It would appear that your sample code was illegally mixing float and integer arguments to the call. The constants 1 and 0 are of type int, unlike 0.0f and 1.0f which are of type float.
See the quick reference card for more details.
I am getting the same problems on the same piece of code (http://www.gamedev.net/blog/1241/entry-2254210-realtime-raytracing-with-opencl-ii/). It is written poorly and managed to hang my pc.
The clamp() problem is indeed fixed by making sure that the last two arguments are floats.
The matrixVectorMultiply() problem is fixed by changing the signature of that function. It originally is:
float3 matrixVectorMultiply(__global float* matrix, float3* vector){
float3 result;
result.x = matrix[0]*((*vector).x)+matrix[4]*((*vector).y)+matrix[8]*((*vector).z)+matrix[12];
result.y = matrix[1]*((*vector).x)+matrix[5]*((*vector).y)+matrix[9]*((*vector).z)+matrix[13];
result.z = matrix[2]*((*vector).x)+matrix[6]*((*vector).y)+matrix[10]*((*vector).z)+matrix[14];
return result;
}
However there is absolutely no reason for vector to be a pointer, so you can remove the * before every occurrence of vector.
Then the code should compile, but the program probably still crashes.
Probably not your issue, but worth noting: Between OpenCL 1.0 and 1.1 clamp changed slightly, so if you are not careful you can have code that compiles in one version and not the other. Specifically, in the OpenCL 1.1 specification, "Appendix F – Changes", "F.1 Summary of changes from OpenCL 1.0" it says "The following features are added to the OpenCL C programming language (section 6):", then "New built-in functions", then "clamp integer function defined in section 6.11.3"
So you're best off fully qualifying your parameters.
Related to this, in OpenCL 1.1 added (vector, scalar) variant of integer functions min and max, so don't use those in 1.0 (cast the scalar parameters to vectors instead).

calculating constant library functions at compile time

I want to use boltzmann constant in my functions. I am using the following code to declare the boltzmann constant
const double boltzmann_constant = 1.3806503 * pow (10,-23);
Will this get calculated at the compile time itself? If now, how should i ensure that it does get calculated at compile time? Any other method to declare the constant?
The pow() function is very unlikely to be calculated at compile time. However, the operation requested is directly expressible in scientific notation, a standard aspect of floating point numbers:
const double boltzmann_constant = 1.3806503e-23;
For a more complex situation, like sin(M_PI / 3), it can be useful to write a program to calculate and display such values so they can be edited into a program. If you do this, do everyone a favor and include a comment explaining what the constant is:
const double magic_val = 0.8660254037844385965883; // sin(M_PI / 3);

C++ sin() returns incorrect results

i have this piece of code
bool Position::HasInLine(const Unit * const target, float distance, float width) const
{
if (!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance))
return false;
width += target->GetObjectSize();
float angle = GetRelativeAngle(target);
float absSin = abs(sin(angle));
return abs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width;
}
Problem i ran into is, that when i debug with gdb and try "p sin(angle)" it returns weird values - for angle 1.51423 it states that sin = 29 (so yes, i am putting in radians :-) ). More weird is, that when i try "p absSin" it always returns 0, and yes, i was on next line, so the "float absSin = abs(sin(angle))" line was already done.
Originaly there wasnt even included cmath, but the M_PI const was returning correct value, though i added #include at the start of the .cpp file just to make sure, but nothing changed.
If it helps, im using linux kernel 2.6.26-2-xen-amd64
Any ideas?
The function abs (as defined in cstdlib) always takes an integer and returns an integer. When dealing with doubles, you should be using fabs instead.
Another version of abs is defined in cmath (#include <cmath>). It is overloaded to accept (and return) both integers and doubles.
You may wish to double-check which version you are using.
shouldn't you be using fabs and not abs? abs takes ints and returns only ints
"for angle 1.51423 it states that sin = 29"
That's most probably an error of observation, not an error of the sin function.
The result should be in range -1 through +1.
Cheers & hth.,