Jump to content

  • Log In with Google      Sign In   
  • Create Account

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Today, 07:53 AM

#5168140 Exception question

Posted by Brother Bob on 21 July 2014 - 07:55 AM

Pointers never deallocate themselves. Use a smart pointer object to manage ownership.

try {
    std::unique_ptr<int[]> ptr(new [10]);
    for (int i = 0; i < 10; i++) ptr[i] = 10;
    throw 1;
} catch(int x)

#5167544 How to keep straight line straight while mapping to non rectangular area

Posted by Brother Bob on 18 July 2014 - 02:47 AM

If you need to add perspective on top of something that doesn't have perspective itself, you need to add that additional perspective information to the texture coordinates instead. See this.

#5166791 OpenGL : GLEW or Qt or else ?

Posted by Brother Bob on 14 July 2014 - 01:55 PM

You probably want GLFW instead of GLEW, since GLEW is not a GUI library at all. However, GLFW is not much of a GUI library either, really, but rather a relatively simple rendering window and input wrapper but no widgets; only the basic rendering and input frameworks. On the other end, Qt is a complete GUI framework as well. It's not really fair to compare the two. For a lightweight wrapper, both GLFW and SDL are popular.


Another question though; if you are more experienced with Java, have you considered using Java? There are frameworks such as LWJGL that may be of interest to you. I haven't used Java at all though, so I cannot comment on it.

#5165771 how to use or ||

Posted by Brother Bob on 09 July 2014 - 04:27 AM


It should be noted that performing your comparisons using multiple Boolean variables means that you cannot take advantage of short-circuit evaluation.


VS2012, compiled with default release mode settings:


Resulting disassembly:


Compilers are very, very smart.


They are, hopefully, also very smart not to do that when the evaluations of the temporary variables have side effects because that would change the meaning of the program. Your example works because the individual conditions does not have any observable side effects. If the expressions have side effects, or otherwise relies on short circuiting to prevent the evaluation of an expression in the condition (for example checking for null-pointer before accessing a member of an object), expanding the expressions to temporary variables before the if-statement won't work.

#5164168 How is this a pass by value?!

Posted by Brother Bob on 01 July 2014 - 06:04 PM

Ivalue will obviously remain 0 since we pass by value, and svalue will become bar(because we use a pointer).


That was my initial response without running the code. To my surprise, after running it, i was right about ivalue, but not about svalue.


Looking at the code again, I realized that foo is actually a literal, hence, it cannot be changed at all. Is that why the pointers are copied by value? Is there some kind of rule about 2 pointers refering to the same literal?

svalue is a pointer variable, and a copy of its value is passed to the set function. The set function then assigns the local variable a new value, but the original pointer remains the same.


Now replace the two set functions with these instead that takes the parameters by reference.

void set(char const *&value)
    value = "bar";

void set(int &value)
    value = 42;

As I said, pointers are variables that work just like any other type. They just happen to have additional functionality that lets you access other objects through the pointer, but the pointers themselves are just values that are copied like any other value.


edit: There is a huge difference between a pointer, and the object a pointer points to. The pointer is copied, but the pointed-to object is not and can be reassigned across functions.

#5164162 How is this a pass by value?!

Posted by Brother Bob on 01 July 2014 - 05:49 PM

Step away from your nested max functions a bit and examine this program.

void set(char const *value)
    value = "bar";

void set(int value)
    value = 42;

int main ()
    int ivalue = 0;
    char const *svalue = "foo";


    std::cout << ivalue << " " << svalue << std::endl;

Now answer these two questions, and understand why the answer is what it is.

  1. Is the value of ivalue 0 or 42?
  2. Does the pointer svalue point to the string "foo" or "bar"?

This is what is the core of the problem with your max functions.

#5164151 How is this a pass by value?!

Posted by Brother Bob on 01 July 2014 - 05:09 PM

I know the code works, the problem is I can't get the: "error, if max(a,b) uses call-by-value" how would it be called by value when we can clearly see it takes pointers and not values?!

You are confused about what is actually passed to the function. In your max-function that is overloaded for char const *, the pointers a and b are not references to the pointers you pass to it, but value-copied of the original pointers. If you are confused about pointers and pass-by-value, it is easier to hide the pointer behind a typedef.

typedef char const *cstring;

cstring max (cstring a, cstring b)
{ ... }

Now compare with passing int, or float, or double, or char, and you'll see that the cstring object, which is a char const *, is actually passed by value.

#5158101 Checking if a bit is set in a byte

Posted by Brother Bob on 04 June 2014 - 08:21 AM


if( (10110 & 10000) == 10000 )
if( (value & mask) == mask )

I wonder, why do some people write "== mask" instead of "!= 0"? I suppose it doesn't matter much when the variable is "mask" and/or you use a function, but I've seen this pattern with huge blocks of hard-coded if checks with duplicated giant enum names everywhere.


Consider what happens if mask contains more than one bit set. Comparing the AND-result against the mask checks if all bits are set, while comparing against 0 checks if any bit is set.


In that case it is not a matter of relative style or convention, but a matter of absolute correctness; one is correct and the other one is wrong.

#5156834 What are constant references used for?

Posted by Brother Bob on 29 May 2014 - 04:08 PM


How will the compiler discern between one overloaded function and the other? Both have the same signature.

In addition to the explanation given by Brother Bob and reiterated by Rattrap, I showed a different example:
m_aChar.Pos() += m_aPlatform.Pos();
Neither m_aChar nor m_aPlatform are const objects in this context (neither were originally declared with const).

Instead, one is being accessed for read and the other for write.
When possible, the compiler will always choose the const method if it exists.

If only the const method existed, the line would be invalid because you couldn’t write to m_aChar.
If only the non-const method existed, both m_aChar.Pos() and m_aPlatform.Pos() would go through the non-const version (which would set a dirty flag on m_aPlatform and needlessly cause an update to its matrix).

Since both exist, the compiler will try to use const for both m_aChar and m_aPlatform, but it will realize that m_aChar is being accessed for write, so it instead must use the non-const version. m_aPlatform is accessed for read so the default (the const version) remains as the compiler’s choice.

L. Spiro

It doesn't matter whether you write to the returned value or just read from it; the function that is called (the const or non-const vatiant) is determined exclusively based on the object it is called on. The non-const is called when possible, and the const is called when necessary.

#5156760 What are constant references used for?

Posted by Brother Bob on 29 May 2014 - 11:56 AM

How will the compiler discern between one overloaded function and the other? Both have the same signature.

The non-const overload is chosen for non-const objects/references, and the const overload is chosen for const objects/references.

#5153825 Vector math help

Posted by Brother Bob on 15 May 2014 - 02:21 PM

Using those same two vectors, calculate the angle between them using the cross product. The book seems to indicate that the following formula is used:

|| a x b || = ||a|| ||b|| sin(theta)
It goes on to explain that's the same as this:
|| a x b || = ||a|| ||b|| sqrt(1 - (a dot b)**2)

This step assumes that cos(theta) = a dot b, but that is only true for unit vectors. For non-unit vectors, such as in you example, the correct equation is

|| a x b || = ||a|| ||b|| sqrt(1 - ((a dot b) / (||a|| * ||b||)**2))

Wikipedia stated that the magnitude of the cross product of the unit vectors yields the sine, but even this isn't giving me the correct angle:

â = (0, 1, 1) / sqrt(0*0 + 1*1 + 1*1) = (0, 0.707, 0.707)

b̂ = (0, -1, 0) / sqrt(0*0 + -1*-1 + 0*0) = (0, -1, 0)

â x b̂ = (.707, 0, 0)

sin(theta) = ||â x b̂|| = .707
So I thought inverse sine of .707 yield the actual angle, but it doesn't reproduce the same value I calculated with the scalar product (2.356):
arcsin(.707) = 0.785
But I have noticed that
arccos(-0.707) = 2.356
So what am I missing here? Please help!


I believe this is a domain ambiguity. You are indeed getting the sine of the angle with the norm of the cross product, but the inverse sine is not necessarily the angle. You have two solutions to sin(x)=0.070, and you're getting one of them; the other one is 180-x. The inverse sine function is defined for -90 to 90 degrees, but your desired solution is at 135 degrees.


edit: The editor broke the code tags and tried to recreate them, in case some code boxes or their contents don't match the original post I quoted.

#5153666 OpenGL missile direction questions

Posted by Brother Bob on 14 May 2014 - 04:26 PM

I don't understand what you mean. If gTanks is a vector of tanks, then gTanks[i] is a specific tank indicated by the index i. I'm merely suggesting that you pass gTank[i] to the missile constructor instead of accessing the global array directly. The missile doesn't have to know about all possible tanks, only the tank that fired it so you know from where and in which direction it was fired.

#5153658 OpenGL missile direction questions

Posted by Brother Bob on 14 May 2014 - 03:42 PM

Visual Studio warned me I can't use cos and sin that way (I have #include <math.h> though).

cos and sin are functions, so you have to pass the angle as a parameter just like you did in the second code listing.

And it also says the i in gTanks[i] is undefined. (I know it's undefined but I don't know how to define my number of tanks in missile constructor...)

What do you intend for i to be? I also assume gTanks is a global array of tanks. I would rather pass the specific tank to the constructor and not rely on global states at all.

Missile::Missile(Tank const &tank) {
    direction[0] = cos(tank.angle);
    direction[1] = sin(tank.angle);

And then you construct you missile by passing the correct tank to its constructor.

Do I set the missile direction in the constructor or do I have to set it in a function?
And is gTanks[i]->angle referring to the calculated angle in the void function (angle += angularVelocity;), or is it referring to tank's constructor angle member?

It is the value of the angle member variable at the time you access it.

#5152505 Why is my texture flipped sideways?

Posted by Brother Bob on 09 May 2014 - 05:09 AM

1: Texture coordinates are in the range from 0 to 1, not from -1 to 1.

2: You need to emit the texture coordinate before the vertex. Your current code is equivalent to:

        // bottom left
        glVertex2f(m_x, m_y);
        // bottom right
        glTexCoord2f(-1.0f, -1.0f);
        glVertex2f(m_x + m_width, m_y);

        // top right
        glTexCoord2f(1.0f, -1.0f);
        glVertex2f(m_x + m_width, m_y + m_height);

        // top left
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f(m_x, m_y + m_height);
        // bottom left for the next display callback
        glTexCoord2f(-1.0f, 1.0f);

#5150991 Extracting basis vectors from a quaternion

Posted by Brother Bob on 02 May 2014 - 03:21 PM

The axis of rotation is not a basis vector. This is only true if you are rotating about one of the principal axes, but not in general.