Porting MFC? If you could do that, I think you''d get an honorary PhD degree from any university you want
Give me one more medicated peaceful moment.
~ (V)^|) |<é!t|-| ~
ERROR: Your beta-version of Life1.0 has expired. Please upgrade to the full version. All important social functions will be disabled from now on.
Unnecessary C++ features?
It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
Getting back to the performance issue with C++ exceptions. Someone, c++freak I think, said that exceptions cause no performance issue unless they are actually thrown. That, to me, does not seem quite true. Let''s have a look at the code generated by VC++6 (with optimizations turned off, however) for a function that does absoultley nothing with no exceptions vs. exceptions.
Perhaps not a great performance hit but indeed a performace hit. I don''t know if optimizations would do any wonders for this though.
"Paranoia is the belief in a hidden order behind the visible." - Anonymous
/* void foo(void) { // do nothing }*/// generates this assembly code:183: void foo(void)184: {00401020 push ebp00401021 mov ebp,esp00401023 sub esp,40h00401026 push ebx00401027 push esi00401028 push edi00401029 lea edi,[ebp-40h]0040102C mov ecx,10h00401031 mov eax,0CCCCCCCCh00401036 rep stos dword ptr [edi]185: // do nothing186: }00401038 pop edi00401039 pop esi0040103A pop ebx0040103B mov esp,ebp0040103D pop ebp0040103E ret/* void foo(void) { try { // do nothing } catch(...) { } }*/// generates this assembly code:183: void foo(void)184: {00401020 push ebp00401021 mov ebp,esp00401023 push 0FFh00401025 push offset __ehhandler$?foo@@YAXXZ (004106e0)0040102A mov eax,fs:[00000000]00401030 push eax00401031 mov dword ptr fs:[0],esp00401038 push ecx00401039 sub esp,40h0040103C push ebx0040103D push esi0040103E push edi0040103F mov dword ptr [ebp-10h],esp00401042 lea edi,[ebp-50h]00401045 mov ecx,10h0040104A mov eax,0CCCCCCCCh0040104F rep stos dword ptr [edi]185: // do nothing186: try187: {00401051 mov dword ptr [ebp-4],0188:189: }190: catch(...)00401058 jmp __tryend$?foo@@YAXXZ$1 (00401060)191: {192:193: }0040105A mov eax,offset __tryend$?foo@@YAXXZ$1 (00401060)0040105F ret194: }00401060 mov dword ptr [ebp-4],0FFFFFFFFh00401067 mov ecx,dword ptr [ebp-0Ch]0040106A mov dword ptr fs:[0],ecx00401071 pop edi00401072 pop esi00401073 pop ebx00401074 mov esp,ebp00401076 pop ebp00401077 ret
Perhaps not a great performance hit but indeed a performace hit. I don''t know if optimizations would do any wonders for this though.
"Paranoia is the belief in a hidden order behind the visible." - Anonymous
RWarden:
Isn''t "intuitive" subjective? I understand what you are saying, but you just can''t confine all new types to use the operators as if they were algebraic numbers. Your example shows how operator overloading can easily be misused, but there is an important difference: it was using one operator to do something that had already been defined for another operator (+ instead of *), rather than giving an operator a completely new definition (as in stream I/O).
As with all language tools, operator overloading can be used or abused.
BTW, no one could defend any points because no one''s making an attack here, right? I just explained them a little bit.
Happy Coding!
- null_pointer
Sabre Multimedia
Isn''t "intuitive" subjective? I understand what you are saying, but you just can''t confine all new types to use the operators as if they were algebraic numbers. Your example shows how operator overloading can easily be misused, but there is an important difference: it was using one operator to do something that had already been defined for another operator (+ instead of *), rather than giving an operator a completely new definition (as in stream I/O).
As with all language tools, operator overloading can be used or abused.
BTW, no one could defend any points because no one''s making an attack here, right? I just explained them a little bit.
Happy Coding!
- null_pointer
Sabre Multimedia
I hate the obscure way C++ is taught... they never tell you why you should do somhting in C++....
Anyways here is a link to STLport (from www.flipcode.com)
http://www.stlport.org/index.shtml
From there, they had a nice link to the SGI stl documentation that is adequate for what I want to know
I'll have to look at that book next month, I am already over my budget. Oh, it is $34.99 at borders.com
"Marriage - when you still get an allowance but call it a 'budget' instead."
Edited by - Whirlwind on July 14, 2000 2:13:04 PM
Anyways here is a link to STLport (from www.flipcode.com)
http://www.stlport.org/index.shtml
From there, they had a nice link to the SGI stl documentation that is adequate for what I want to know
I'll have to look at that book next month, I am already over my budget. Oh, it is $34.99 at borders.com
"Marriage - when you still get an allowance but call it a 'budget' instead."
Edited by - Whirlwind on July 14, 2000 2:13:04 PM
Here''s some of my thoughts:
--- Performance costs of Exceptions -
Basically, most of the cost is associated with dtor calls during stack unwinding. However, that can happen even when you are not using try, catch, and throw.
For example:
class MyType;
void Func()
{
MyType thing;
thing->Something();
}
This function incurs almost the same performance overhead as the same function including a try/catch block.
A function ( or block scope ) that only uses built-in automatic types ( including pointer to objects ) types and does not use other inline functions, does not incur this penalty.
You shouldn''t worry about the performance penalty of exceptions when one is thrown - after all, that is exceptional
So the bigger issue is how you use your classes.
--- References
Absolutely necessary. I''m not sure if others have pointed out the key difference between a C++ reference and a C++ pointer. A reference CANNOT be null. This is the main reason why passing by const reference is a good thing (tm) - you don''t have to check for null.
The reason why pass by non-const reference is generally considered a bad thing (tm) is because it looks like pass by value in client code, even though it is not.
--- STL
I love it. Who wants to code list and array classes? I want to write code for games!
Although it can be daunting to try to learn it all - just learn what you need to use.
--- volatile
volatile can be essential when you know you''re optimizing compiler may be making assumptions that aren''t necessarily valid about when it needs to reference a real memory location rather than just a register
--- static_cast
I think this is very useful. Changing to the C++ casting operators means using static_cast which will not always let you do the same thing that you can with a C class, and in fact you want this so you can see at compile time if certain types casts are based on bad assumptions
--- object creation at a specific address
Also known as placement new. Basically, this syntax separates raw memory allocation from constructor calling.
This is critical if you want to write your own memory allocation routines for objects.
I have used this to implement block memory allocation template arrays.
I''ve also seen it used for pool allocator of objects.
--- private inheritance
e.g. class A : private B
I''ve used this and I do think it can be useful, although you can often achieve the same thing via composition.
e.g.
class A
{
B iItsB;
};
But private inheritance designates inheriting implementation, as opposed to public inheritance which designates inheriting interface ( and implementation if it comes along with it )
One thing I think I have found no use for in C++ is supporting the old malloc() and free(). Granted, that''s the only way to get at a realloc() and most new and delete implementations are on top of those functions, but eventually those have to go down to real OS specific memory routines.
But being that C++ is ''mostly'' compatibly with C, I can understand why it is in there. I just avoid it.
--- Performance costs of Exceptions -
Basically, most of the cost is associated with dtor calls during stack unwinding. However, that can happen even when you are not using try, catch, and throw.
For example:
class MyType;
void Func()
{
MyType thing;
thing->Something();
}
This function incurs almost the same performance overhead as the same function including a try/catch block.
A function ( or block scope ) that only uses built-in automatic types ( including pointer to objects ) types and does not use other inline functions, does not incur this penalty.
You shouldn''t worry about the performance penalty of exceptions when one is thrown - after all, that is exceptional
So the bigger issue is how you use your classes.
--- References
Absolutely necessary. I''m not sure if others have pointed out the key difference between a C++ reference and a C++ pointer. A reference CANNOT be null. This is the main reason why passing by const reference is a good thing (tm) - you don''t have to check for null.
The reason why pass by non-const reference is generally considered a bad thing (tm) is because it looks like pass by value in client code, even though it is not.
--- STL
I love it. Who wants to code list and array classes? I want to write code for games!
Although it can be daunting to try to learn it all - just learn what you need to use.
--- volatile
volatile can be essential when you know you''re optimizing compiler may be making assumptions that aren''t necessarily valid about when it needs to reference a real memory location rather than just a register
--- static_cast
I think this is very useful. Changing to the C++ casting operators means using static_cast which will not always let you do the same thing that you can with a C class, and in fact you want this so you can see at compile time if certain types casts are based on bad assumptions
--- object creation at a specific address
Also known as placement new. Basically, this syntax separates raw memory allocation from constructor calling.
This is critical if you want to write your own memory allocation routines for objects.
I have used this to implement block memory allocation template arrays.
I''ve also seen it used for pool allocator of objects.
--- private inheritance
e.g. class A : private B
I''ve used this and I do think it can be useful, although you can often achieve the same thing via composition.
e.g.
class A
{
B iItsB;
};
But private inheritance designates inheriting implementation, as opposed to public inheritance which designates inheriting interface ( and implementation if it comes along with it )
One thing I think I have found no use for in C++ is supporting the old malloc() and free(). Granted, that''s the only way to get at a realloc() and most new and delete implementations are on top of those functions, but eventually those have to go down to real OS specific memory routines.
But being that C++ is ''mostly'' compatibly with C, I can understand why it is in there. I just avoid it.
July 14, 2000 11:15 PM
Getting back to performance issues with C++ exceptions, once more.
On the code presented by Staffan. The function,
in your listing without optimizations should only result in 4 statements. I bet you compiled in Debug mode. Everyone should remember in VC (and all the others with Debug/Release modes from what I know) that the Debug build is not the same as the Release build. The Debug build has alot of extra stuff and ignores most (or is it all?) optimizations. I''m also less sure about the other compilers on this one.
Here''s the 4 lines I get and they sure look like an optimizer ought to know to take the whole damn thing out. Of course, this is a silly function.
Now the try/catch version still had all (or most since I didn''t go do a detailed check) of the code your listing does. For more realistice functions without try/catch I think the savings from code is still somewhat significant though.
And now a reading from the Holy Scriptures, MSDN 4:16.
Yeah, don''t throw exceptions everytime your characten hits a wall.
Another major performance hit for exceptions is that unwinding the stack and shifting the ip can cause a series (or would it be just one?) of cache misses. Another reason to only use them for the exceptional "oh my god" errors that aren''t supposed to be happening anyway.
Beware, I will start the "For ''Vs. Threads''" Vs. "Against ''Vs. Threads''" thread if I must.
Mike Roberts
aka milo
mlbobs@telocity.com
On the code presented by Staffan. The function,
void foo(void){}
in your listing without optimizations should only result in 4 statements. I bet you compiled in Debug mode. Everyone should remember in VC (and all the others with Debug/Release modes from what I know) that the Debug build is not the same as the Release build. The Debug build has alot of extra stuff and ignores most (or is it all?) optimizations. I''m also less sure about the other compilers on this one.
Here''s the 4 lines I get and they sure look like an optimizer ought to know to take the whole damn thing out. Of course, this is a silly function.
push ebpmov ebp, esppop ebpret 0
Now the try/catch version still had all (or most since I didn''t go do a detailed check) of the code your listing does. For more realistice functions without try/catch I think the savings from code is still somewhat significant though.
And now a reading from the Holy Scriptures, MSDN 4:16.
quote:
The extra overhead associated with the C++ exception handling mechanism may increase the size of executable files and slow program execution time. ...
Because of the nature of exception handling and the extra overhead involved, exceptions should be used only to signal the occurrence of unusual or unanticipated program events. Exception handlers should not be used to redirect the program’s normal flow of control. For example, an exception should not be thrown in cases of potential logic or user input errors, such as the overflow of an array boundary. In these cases, simply returning an error code may be simpler and more concise. Judicious use of exception handling constructs makes your program easier to maintain and your code more readable.
Yeah, don''t throw exceptions everytime your characten hits a wall.
Another major performance hit for exceptions is that unwinding the stack and shifting the ip can cause a series (or would it be just one?) of cache misses. Another reason to only use them for the exceptional "oh my god" errors that aren''t supposed to be happening anyway.
Beware, I will start the "For ''Vs. Threads''" Vs. "Against ''Vs. Threads''" thread if I must.
Mike Roberts
aka milo
mlbobs@telocity.com
Whirlwind: Yeah, I know. I blame a lot of poorly written tutorials and books for not teaching _how_ to use C++. What good is knowing what a feature does, if you don''t know how it fits in with the other features in a language? If you want a great book on C++ that _does_ explain the "how" of the language, check out "C++ for Dummies, 3rd Edition" from IDG Books, Inc. Don''t worry about the title - it''s a solid book with lots of examples and explanations. It''s where I learned most of what I know about C++ (not that I know everything - God forbid!).
- null_pointer
Sabre Multimedia
- null_pointer
Sabre Multimedia
Anonymous: If you read the post you would have seen I stated the code was taken from code with _all_ optimizations off, yes all of them.
"Paranoia is the belief in a hidden order behind the visible." - Anonymous
"Paranoia is the belief in a hidden order behind the visible." - Anonymous
quote: Original post by Staffan
Anonymous: If you read the post you would have seen I stated the code was taken from code with _all_ optimizations off, yes all of them.
Yes, I did see that. But Debug Vs. Release is not optimization and that, I believe, is where most of your extra code is coming from with the first function.
And I just noticed that I''ve been showing up as Anonymous Loser, so I''ll have to go figure out WTF is happening with that.
Mike Roberts
aka milo
mlbobs@telocity.com
I don''t know if anyone will read my questions, but this really is a good thread.
There are a few big issues in C++ that I just don''t get (lack of effort I suppose)
1. What is the difference between a typedef and a struct?
2. What do you all use STL for?
3. (Back to game development)Should I use inherited classes and virtual functions for different units, or just one class with a bunch of switches in the code? On the one hand, I have to delete and recreate each time if I use inherited, and some other headaches, but on the other hand the code is more intuitive and readable.
4. Is there a better way to do 2d than DDraw? It is a real pain sometimes.
5. Plain old C sucks (whoah, there, my instincts got the better of me, sorry about that)
Thanks is advance, guys!
Check out my d/l site at here
~BenDilts( void );
There are a few big issues in C++ that I just don''t get (lack of effort I suppose)
1. What is the difference between a typedef and a struct?
2. What do you all use STL for?
3. (Back to game development)Should I use inherited classes and virtual functions for different units, or just one class with a bunch of switches in the code? On the one hand, I have to delete and recreate each time if I use inherited, and some other headaches, but on the other hand the code is more intuitive and readable.
4. Is there a better way to do 2d than DDraw? It is a real pain sometimes.
5. Plain old C sucks (whoah, there, my instincts got the better of me, sorry about that)
Thanks is advance, guys!
Check out my d/l site at here
~BenDilts( void );
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement