Author Topic: Compile error  (Read 12312 times)

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #15 on: February 07, 2006, 11:58:50 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

sethjackson

  • Guest
Re: Compile error
« Reply #16 on: February 07, 2006, 07:39:29 pm »
How do I use try/catch?

Code: C++
  1.         unsigned char* data;
  2.  
  3.         // Try to allocate some memory.
  4.  
  5.         try
  6.         {
  7.              data = new unsigned char[imageSize];
  8.         }
  9.  
  10.         // Show an exception message if we can't allocate the memory we need.
  11.  
  12.         catch(bad_allocation)
  13.         {
  14.             wxSafeShowMessage(_("Exception"), _("Memory allocation failed! The application will terminate immediately..."));
  15.         }
  16.  
  17.  

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

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #17 on: February 07, 2006, 07:48:33 pm »
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.
« Last Edit: February 07, 2006, 07:50:39 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #18 on: February 07, 2006, 08:01:30 pm »
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."

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Compile error
« Reply #19 on: February 08, 2006, 02:16:50 am »
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
  1. int[] myArray = new int[10];
  2.  
  3. try {
  4.   int index = 0;
  5.   while(true) {
  6.     system.out.println(myArray[index])
  7.     index++;
  8.   }
  9.   // Finished the loop
  10. }
  11.  
  12.  
« Last Edit: February 08, 2006, 02:22:24 am by Game_Ender »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Compile error
« Reply #20 on: February 08, 2006, 10:04:56 am »
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."

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: Compile error
« Reply #21 on: February 08, 2006, 11:19:44 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.:

Code: [Select]
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

Offline jmccay

  • Almost regular
  • **
  • Posts: 202
Re: Compile error
« Reply #22 on: February 09, 2006, 02:31:29 am »
@polygon7

Why the
Code: C++
  1. << 2
instead of
Code: C++
  1.  * 4
?

This line

Code: C++
  1. unsigned long imageSize = (image.GetWidth() * image.GetHeight())  << 2;
  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.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: Compile error
« Reply #23 on: February 09, 2006, 03:16:04 am »
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: C++
  1. b = a * 4;

The compiler outputs:
Code: ASM
  1. movl    -4(%ebp), %eax
  2. sall    $2, %eax
  3. 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: C++
  1. b = a * 5;

into:
Code: ASM
  1. movl    -4(%ebp), %edx
  2. leal    (%edx,%edx,4), %eax
  3. movl    %eax, 4(%esp)

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