News:

As usual while waiting for the next release - don't forget to check the nightly builds in the forum.

Main Menu

Compile error

Started by sethjackson, February 05, 2006, 10:22:34 PM

Previous topic - Next topic

Michael

Quote from: killerbot on February 07, 2006, 11:13:51 AM
Normally when new fails, it throws -> catch it.
There exist a no_throw new. I think it is not portable, the gurus (Sutter, ..) give the advice not to use it. So just forget you ever heard about it ;-)

Normally, I always use the throw new :). But, there was a mention of the no-throw new in the book C++Primer (4th Edition) written by
Stanley B. Lippman et al. I will give a check in the C++ standard book later. Until now, I have just found that you can overload the operator, but how this will influence the portability, it was not written :(.

Michael
[url="http://img207.imageshack.us/img207/9728/411948picture4em.png"]http://img207.imageshack.us/img207/9728/411948picture4em.png[/url]

sethjackson

How do I use try/catch?

Code (cpp) Select

        unsigned char* data;

        // Try to allocate some memory.

        try
        {
             data = new unsigned char[imageSize];
        }

        // Show an exception message if we can't allocate the memory we need.

        catch(bad_allocation)
        {
            wxSafeShowMessage(_("Exception"), _("Memory allocation failed! The application will terminate immediately..."));
        }



Sorry I'm new to this type of error handling....  :P

thomas

#17
You need to provide a type in the catch ( ) clause. Except for that, it's ok.

Alternatively, you can use catch ( ... ) if you want to catch all. Then, however, you don't know what you have caught (often, that's acceptable).

EDIT:
Oh yes... the reason why you have to provide a type is that you can catch different things from the same try block (in case that more than one thing can go wrong). The catch block whose type matches the exception thrown is executed and you get the exception similar to a function argument.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

thomas

Another thing: You are using exceptions in an OpenGL application. I don't know what exactly you're programming there, but if it is something that is really CPU-intensive (which may happen to be the case here), then you should be aware that exceptions are not free.

Catching an exception (which luckily only happens in the exceptional case) takes a lot of CPU time, on the order of tens to hundreds of microseconds.
However, even if you do not throw and catch exceptions, your code runs somewhat slower (something on the order of 2-4%, depending on the compiler and the program). Often, this does not matter much, but then, sometimes it does. Thus, think clearly whether you really need exceptions in a CPU-intensive application.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Game_Ender

#19
Thomas makes a good point but I don't you think you should throw them away out of hand.  Almost everyone spends time making "optimizations" on areas that don't need any.  I say use exceptions carefully and if you run into performance problems pull back there use.

Take a look at Ogre.  It is a high performance 3D rendering engine.  It uses exceptions, but only where they are appropriate, like when a resource fails to run or you have done something to crash the render system.

The overall important rule for exceptions to use them for program flow control, that means don't check for thing with exceptions.  This rough java snippet below is a good example of what not to do:

Code (java) Select

int[] myArray = new int[10];

try {
  int index = 0;
  while(true) {
    system.out.println(myArray[index])
    index++;
  }
} catch (ArrayIndexOutOfBoundsException e)
  // Finished the loop
}


thomas

Right, like I said, sometimes it does not matter, and sometimes it does. Although I disagree on Ogre ;)
Ogre is a good example where I think exceptions are actually out of place. It certainly works. And it works excellent, too. But the main purpose of Ogre is to create games. Today, the GPU usually has plenty of cycles left while on the other hand, the game is utterly CPU-bound. You have to try very hard to be GPU-bound (unless you write very very expensive shaders).
Thus, it seems to me that losing a couple of percent of CPU time to exception handling may not precisely be what you want to do.
Of course, things like scripting easily eat up 10-20 times as much CPU as EH, but you usually cannot do without scripting.

The problem with EH is that even if you only use exceptions where appropriate, you can only compile with or without exception handling, and unless you use compiler-specific attributes (such as nothrow), the compiler has a very hard time knowing where to add stack unwinding code and where not to (most will simply insert code everywhere).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Michael

Quote from: killerbot on February 07, 2006, 11:13:51 AM
There exist a no_throw new. I think it is not portable, the gurus (Sutter, ..) give the advice not to use it. So just forget you ever heard about it ;-)

I have had a look at the C++ Standard book and I have found that the two possibilities for the operator new are described and there are no constraints in using the throw-new instead of the nothrow-new. There is written something as: "If the program wishes...". Personally, I have never used the nothrow-new, but I prefer it, even if I have to specify nothrow, e.g.:


int* ndata = new(nothrow) int;
//do something with ndata
delete ndata;


I have also not found portability issues by searching with Google. May be this is due on how C++ standard compliant are the different compilers.

Michael
[url="http://img207.imageshack.us/img207/9728/411948picture4em.png"]http://img207.imageshack.us/img207/9728/411948picture4em.png[/url]

jmccay

Quote from: polygon7 on February 05, 2006, 11:01:47 PM
Quote from: sethjackson on February 05, 2006, 10:55:55 PM
@polygon7

Why the
Code (cpp) Select
<< 2 instead of
Code (cpp) Select
* 4?

This line

Code (cpp) Select

unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;

"<<" is shifting bits operator (shift left, SHL in assembly). SHL can be used for multiply by power of two (SHR, shift right for dividing by power of two).

x*2 == x <<1, x*4 == x <<2 ...

Bit shifting usually is faster then normal multiply.

I would like to add (because not everybody might know it) that there is one advantage to using the bit shifting operators over a normal multiplication/division.  On some systems (since I don't know all systems and my assembly language is rusty I will use "some"), the operator translates to an assembly/machine language command that is faster than multiplication & division.  It was/is a technique used by game developers for faster mathematics when manipulating images.  They would make the images multiples of 2 to be able to use it.

jmccay
OS: WinXP, Win98 SE, & sometimes Linux

a little light reading from the wxWidgets 2.6.2 readme: A detailed 2000-page reference manual is supplied in HTML, PDF and Windows Help form: see the docs hierarchy.

Ceniza

Well, if you take a look at the compiler's output, even without optimizations (GCC), using * 4 or << 2 generate the same code, but * 4 is still more readable.

For this code:
Code (cpp) Select
b = a * 4;

The compiler outputs:
Code (asm) Select
movl -4(%ebp), %eax
sall $2, %eax
movl %eax, -8(%ebp)


There're many things compilers can handle by themselves, including such simple optimizations, and a few more advanced ones that can only be achieved in ASM.

Specifying optimizations (like -O3) will give you better results, like converting:
Code (cpp) Select
b = a * 5;

into:
Code (asm) Select
movl -4(%ebp), %edx
leal (%edx,%edx,4), %eax
movl %eax, 4(%esp)


As you can see those early optimizations just make your code less readable for the same output and performance.