Archived

This topic is now archived and is closed to further replies.

Unnecessary C++ features?

This topic is 6356 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I started this thread so that if anyone can think of an unnecessary feature in C++, something they do not understand how to use very well, or anything different between C and C++ that you could post here and someone might reply and explain it. Perhaps there are unnecessary features in C++. Perhaps C++ is worse than C. We''ll find out if we keep an open mind, right? I''ll try to answer what I can, but keep in mind I don''t know everything! There are other people here who know quite a bit more about C++ and the assembly it typically generates - I hope they''ll reply to this post. (I hope to avoid the tension of C vs. C++ posts, and make this post a bit more educational. Rather than saying "C is worse than C++" it would be good to see whether C++ really measures up as a language by itself. ) DISCLAIMER: I AM NOT GOD. DO NOT EXPECT ME TO BE PERFECT. Oh, before I forget! I''m looking for things like: C++ keywords (like if, else, etc.) STL classes/functions (like auto_ptr, list, etc.) Features that are not keywords (like operator overloading) C++ syntax (like "x += 7") I don''t want discussion about OOP vs. structural - it''s just too vague. Or programming methodology wars. Just the C++ language. You could ask about the class and virtual keywords if you want, though. Happy Coding!
- null_pointer Sabre Multimedia

Share this post


Link to post
Share on other sites
[ nice topic, null_pointer. I mean that in a very serious way ]

I''ll be the first to post a question here, to know other people''s opinions.

This is about C++ exceptions, and the overhead they generate.

I know how to use try, catch and throw myself, but I never really have. I think it is because it''s such a large unknown as far as performance is concerned, and I''m usually writing high-performance stuff to be shared among many people.
I''d love to use C++ exception handling, but can anyone tell me what I''ll be paying for it in terms of performance/object file size?

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.

Share this post


Link to post
Share on other sites
Hi.

Well, IMO, the assignment shortcuts, declaring variables in the middle of a statement, and the -- and ++ operators (except may be in the FOR statement), are unnecessary.

The "variable += variable1" confuses me, and I rather increase/decrease variables in a separate statement.

May be I am just old fashioned, i don''t know.

Topgoro

Share this post


Link to post
Share on other sites
The name says it all .
Anyways, var1 += var2 is actually, performance wise, better then var1 = var1 + var2, because in the first, you do 1 addition, 1 ''get'' and one ''set'', whereas in the second, you do 1 addition, 2 ''get'' and one ''set''. Ok tiny performace, but if you do it 1000 times that adds up... right....
Anyway operator overloading is great. What would YOU rather do:
Matrix M,M2;
M = M.Multiply(M2);

Matrix M,M2;
M = M * M2;

Performance wise, lets see:
M * M2 is actually M.operator*(M2) which is performance wise the same as M.Multiply(M2). So no loss of speed, increase of readability, ease of use, etc... Which saves in the long run, a lot of coding time think - *M2 is 11 characters less then M.Multiply(M2). Times that by a few thousands times, even if you are a fast typer... adds up. Operator overloading is merely renaming functions to different names, and getting the compiler to call them, instead of you. This is more noticeable when you see the declaration for a operator overloaded operator:
class XYZ {
public:
XYZ& operator*(XYZ& Other); //is the same as:
XYZ& Multiply(XYZ& Other);
};


STL classes.
Ok, perhaps not so necessary. Lets see: the play of life.
1) programmer writes list class.
2) programmer feels great.
3) programmer reads about STL.
4) programmer thinks: is it better to use stl then my list class?
5) programmer either uses STL, kicks himself for wasting time, and gets on with it.
5) programmer convinces himself that he should reinvent the wheel, writes a set of containers taking about 2 or 3 weeks, another 2 debugging, etc etc.

Obiviously you can see my slant here...
I use the STL all the time (map class being the best). I really really hope that some day, they make the STL more ,well, NOTICEABLE then it is now. Then it would save a lot of time. Think: how many list classes do you think everyone has made??? a few thousand at least. times that by an average of 3 weeks makes 3000 weeks - WAIT! NO OOP vs STRUCTURAL. Oh well. Still, hope you can see where i''m going..

C++ keywords.
Well, now. C has them too. So they can''t be unnecessary. (NO if''s else''s are you CRAZY!) where are you going to branch code? No user input! IMHO!

The & syntax whatever.
This is important, to you Performance buffs. Very necessary. Take function x:
void x(ABigClass y) {}
Function x must copy y every time it is run. You can''t change y, either (well you can, but the changes will be lost). So to get around this:
void x(ABigClass* y) {}
Which is at the assembly level nearly the same as:
void x(ABigClass& y) {}
but without all those ->. Usual compiler implementations define & as simply a pointer to a point in the memory, with the stack on the calling sides of the function setting up the pointer to point to the argument, and the function side setting up a temporary argument that uses the pointer. Saves all that copying around. I use it mainly for operators, saving copying every time I do:
M = M*View.
or whatever.

Oh yeah, C++ can''t possibly be worse then C. Argument: C++ is built on C. So if C++ is worse, that means C is worser, which means nothing changed. If you don''t like C++ stuff, don''t use them. C++ doesn''t force you to use C++. Obiviously.

Whew! Who would of thought I would of written this much!

Share this post


Link to post
Share on other sites
quote:
Original post by c++freak

Oh yeah, C++ can''t possibly be worse then C. Argument: C++ is built on C.



Null_pointer specifically asked to stay AWAY from comparing C to C++, we''ve both been there before, and there is no point starting it up again.

( I can refute the claim anyway, by saying that excess baggage is not necessarily a good thing, and more features can in fact be worse instead of better. )



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.

Share this post


Link to post
Share on other sites
Oh yeah, about exceptions:
Basically they incur no performance (I could be wrong though) overhead _UNTIL_ the exception is (ever) thrown. Of course there is some code size overhead, but that isn''t that much compared to a usual game''s size (1 MB or so for a simple 3d walkaround). Once the exception(s) are thrown,at that point, the stack is unwound (functions are ''un''called) until a ''catch'' is found. If so, the handling code is called (usually: ''ERROR: Exception xyz has been thrown. Somethings wrong. Bye!'') and then, the stack is rewound to the point where the exception was thrown. Oh yeah, when the stack is getting wound up and unwound, all that happens is that the stack order is messed around with, and the code execution pointer is messed with too, no actual performance hit. Mainly, when you use exceptions, is for things like no file exists, DX isn''t working, GL doesn''t have all the libaries, etc. that will terminate the game/app, so that any performance hit - at that point - will not matter. To reiterate - there is no performance hit until a exception is called.
On using exceptions:
create a exception class, or USE the STL ones. All that it must do is contain a string stating the message/error. For even better exceptions, make a DXError or whatever class derived from that, that turns a HRESULT to a string.Now, when the mode is not supported by the device:
instead of:

if FAILED(xyz)
return hr;
....

if FAILED(LoadDX()) {
MessageBox("Error","Error",other parameters here);
return;
}

do:

void CheckHR(HRESULT New) {
if(FAILED(New)) throw(DXError(New)); //will turn HRESULT to string
}
...
hr = SetDisplayMode(x,y,z);
CheckHR(New);
...
LoadDX(); //NO ERROR CHECKING!!

and in the winmain:
int winmain(....) {
try {//first thing. VERY important.
... //all code here. windows stuff, dx/gl stuff, game loop etc.
}//last thing.
catch(Exception& AException) {
MessageBox(NULL,"Error",AException.String,MB_OK);
return 1;
}

So now, there is no error checking, and one big try/catch statement to catch all errors. You might want it so that you could have Error levels (Fatal,Big,OutDebug) so that some errors terminate the app, some show it via messagebox, some outputdebugstring the message.

Share this post


Link to post
Share on other sites
I don''t like STL since there is no place to go to see what is out there, so it really isn''t needed. Show me a book that lists and describes STL. Ditch STL.

Share this post


Link to post
Share on other sites
I kinda like the var+=var2 and var++ type of thing....

it''s a lot quicker to type at least

"The road of excess leads to the palace of wisdom." --William Blake

Share this post


Link to post
Share on other sites
(Whirlwind)
Show me a book that lists and describes STL

Haven''t you heard of compiler documentation? What compiler are you using? (VC++ I would guess, Borland always has documentation ). There should be documentation for the STL with your compiler. There was documentation for the SGI implementation of the STL out on the web, I forgot where though... Would you rather spend 2 or 3 hours learning the stl then a few weeks implementing a copycat container system? Up to you..

Share this post


Link to post
Share on other sites
This is turning into quite a nice thread!


c++freak:

I meant any keywords, not all keywords.

viz. template, typename, class, register, etc.

BTW thanks for trying to stay away from C vs. C++! I just want people to discuss C++ by its features and not get into a language war.


Whirlwind:

If you go into your compiler documentation, there should be an explanation of each STL class and its member functions, plus some examples (which can be accessed through the help for the member functions). You do have to hunt around a bit for it though.

Basically, STL is a lot of typedefs and some very useful classes. They start small (like pair, auto_ptr, etc.) and keep building upon those objects. It is a very well designed library - plus it reduces the size of my code quite a bit. Instead of writing a map class myself to hold the images in my map editor, I use this code:


map<unsigned int, image> images;



which enables me to place an int in each of my map tiles and objects, indicating which image to use when I want to draw that tile or object. I then go to the map of images, give it the ID, and I get the corresponding image. It''s quite a lot better than tracking objects based on their pointers, I assure you:


display_surface.copy(images[ID], tile.x, tile.y);



Not only that, but I am using vectors to hold the tiles and objects, which are -fast-. I''d show how small the actual source for the map editor is, but I can''t release it to the public. I just wanted to give an example of how it could be used.

Also, when I wrote a font engine, I used this code in each font object:


map<char, image> images;



which allows me to go through an STL string, use it as an array, and print out the corresponding image from the map class. That is:


for( int x=0; x < mystring.size(); x++ )
display_surface.copy(images[ mystring[x] ]);



Of course, you need to add code to keep track of the new position of each letter as you are drawing it, but you get the idea: find the current char, then get its image, and copy it to the screen.

Then there is always the optimization stage. Since I had the same amount of characters (256) and the same range (0-255), I just used a vector that contained 256 images instead of mapping characters to an image with the map class.

IMHO, since all programming is manipulating data, and STL is a powerful tool for manipulating data, STL is invaluable for C++ programming. Of course, that''s just my opinion.


Happy Coding!





- null_pointer
Sabre Multimedia

Share this post


Link to post
Share on other sites
I am a book man myself. I hate digging for information. A physical list would be really nice to find in a book. The online documentation ''craze'' doesn''t do me any good. That would be another non-C++ specific thing to go away. They get rid of a paper manual and don''t bother reducing prices. STL online references are near useless to see if something exists that you want to do.

Share this post


Link to post
Share on other sites
Hmm, I found the references useless. Basically a pointer to a pointer is passing by reference so if you are too lazy to type out ** then I guess it isn't. It adds more confusion than anything, becuase it isn't a pointer and it isn't a variable, so it has no logical place.

-----------------------------

A wise man once said "A person with half a clue is more dangerous than a person with or without one."

Edited by - immaGNUman on July 13, 2000 12:24:01 PM

Share this post


Link to post
Share on other sites
On the ++, -- operators

One thing about the ++ -- += -= etc. operators, when C was first developed, compiler optimization wasn''t very far along. These operators were added to take advantage of specific PDP instructions (can''t tell you which ones since I cut my teeth on the VAX processor and not the PDP.)

Many times, the optimizing compiler will optimized out such things as ''a = a + 1''. With today''s compilers, there is really no telling when the compiler might convert a ''a = a + x'' expression into a ''a += x'' or visa-versa.

Tim

Share this post


Link to post
Share on other sites
Personally I think they implemented iterators in STL very well. On another note though, I can''t STAND the implementation of templates in Visual C++. I can''t even put declarations and definitions in separate files, which really bothers me...

Share this post


Link to post
Share on other sites
The reference operator (&) is VERY important in C++. You really see it shine when overloading operators. It also allows you to treat objects more consistantly in the arguments lists. If you look at my code, you will see a lot of stuff like ''const CMatrix &m'' in argument lists. This allows me to conceptually pass a matrix around as if it was just another simple variable and not some large structure.

Tim

Share this post


Link to post
Share on other sites
Placing template function definitions in a different source file was not even allowed until recently in the standard (if I have my dates right). Currently, most compilers do not support this. One nice thing on the horizon is template libraries without sources.

It is still going to be a while before the compilers catch up with the standard.

Anybody know what compilers support external template definitions?

Tim

Share this post


Link to post
Share on other sites
quote:
Original post by TimSmith

Anybody know what compilers support external template definitions?




I know borland''s free command-line compiler does a MUCH better job at the ANSI templates standard than Visual C++, but I think that even that one doesn''t support external template definitions.

On the topic of references, it''s been said in this thread already, but they do not provide additional functionality, they provide transparency for a certain concept - passing by memory location.
I think that it''s a legacy thing though, really, every argument could be a const ref by default, unless you explicitly say it''s a variable parameter ( by making it a pointer, or whatnot ). Just one of the things you have to live with when using C++ .

[personal thoughts coming]
I personally think that anything that is NOT a const reference, is dangerous. You need it for operator overloading of course, but that''s really the only place I wouldn''t think twice or three times before using a non-const reference. The caller side cannot see if the argument will be changed or not.
Hmm, that makes me wonder, can you cast something to const?
for instance foo( (const)i ); which would generate a compiler error if i was changed anywhere in foo()?
Okay, I''m on my weird track again, ignore me




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.

Share this post


Link to post
Share on other sites
It''s impossible to think(altought you did) that C++ can be worse than C. Like somoene said(I do not remember who), C++ was built in C. And C++ is a upgrade of C! It''s got to better.

I say the upgrade is better than the original version ''cuz it wasn''t made by Microsoft, the WindowsNT service packs are examples of this, the upgrades fix some errors and take a hundred new ones.

Thanks, Arthur(rockslave)

Share this post


Link to post
Share on other sites
someone said something about declaring variables anywhere in the code is useless...i disagree.

eg:

    
void func(int num)
{
int anArray[100000]; //in C you gotta declare the array at the top


if(num < 10)
return;

//...impl

}


if num is 3, then you just wasted your time allocating all that memory for the array.

Share this post


Link to post
Share on other sites
POINT: just what I was going to say.

Actually, in your particular example it doesn''t matter. When you declare local variables in a function, it works the same space-wise in C and in C++: the compiler pre-calculates how much memory will be required for all those variables, and allocates all that space on the stack. It does this all at once, so having an int[20] will not be any faster than having an int[2000]--it''ll just take up more stack space.

The DIFFERENCE in performance is that if any of those objects have constructors, they''ll be called when declared. So if you have a hefty constructor, and you need to return before the construction happens, you just saved that time.

But the main reason I really like this feature is because it makes the code so much more readable. I''m having to go through someone else''s work right now and fix bugs/clean it. It''s a C++ project, but he''s old-school so he declared every single friggin'' variable at the top of the function. The function is over 2000 lines long. Guess who''s lost? Guess how many "unreferenced variable" warnings I get every time I toss a bit of code, then have to go fishing for them? (oh, and there''s absolutely no way to tell which variables belong to the function and which belong to the class because he refuses to put m_ in front of member variables).

OK, bitch mode off.

References kick ass. An intern asked me yesterday: I want to return a pointer with this function, but I don''t want them to do anything whacky like delete it or make it point to something else. Voila! Return a reference, not a pointer.

Share this post


Link to post
Share on other sites
Useless C/C++ features:

- the auto keyword
- class ClassA : private ClassB
- overloading the ~ operator
- MFC =)
- volatile
- static_cast
- iso646.h

Well, some of them have a few uses.. I guess. Oh, on the topic of this thread, I''d like to bitch about operator overloading. I think it''s one of the coolest things about C++, but it really pisses me off when people overload an operator to do something completely unintuitive and/or contradictive to its default nature in the language. In fact I refuse to use iostream simply for that reason.. when I see >> I see a right shift, not stream input!

-RWarden (roberte@maui.net)

Share this post


Link to post
Share on other sites
Nice thread null_pointer. And good job on staying on track everyone.

In order I remember:

Exceptions expand into a branch, and use stack unwinding to find the catch statement as c++freak said.

I don't use STL much, wrote my own templates for collections / arrays / lists / maps a while ago, and use them since I know what's going on there.

For references, I don't use them either. Of course for operator overloading and such, but I'd rather pass pointers in all other situations.

RWarden - volatile has a very specific function in multithreaded environments, but I wouldn't call it useless. It tells the compiler not to store a value in a register and to reload it from memory on every access. Very important on loops such as:


int gUsers;

void Thread1()
{
while(gUsers)
{
//DO WORK HERE THAT DOESN'T TOUCH gUsers
}
}




Edited by - Jon Juan on July 13, 2000 4:21:10 PM

Share this post


Link to post
Share on other sites
Hi all.

Quote by c++Freak
quote:
Anyways, var1 += var2 is actually, performance wise, better then var1 = var1 + var2, because in the first, you do 1 addition, 1 'get' and one 'set', whereas in the second, you do 1 addition, 2 'get' and one 'set'. Ok tiny performace, but if you do it 1000 times that adds up... right....


I compiled the following using VC++ (SP3):

a = a + 1;
a += 1

and both gave exactly the same code (except using diferent processor registers), when looking at the debuger's disassembly mode:


4: a = a + 1;
0040102F mov eax,dword ptr [ebp-4]
00401032 add eax,1
00401035 mov dword ptr [ebp-4],eax
5: a += 1;
00401038 mov ecx,dword ptr [ebp-4]
0040103B add ecx,1
0040103E mov dword ptr [ebp-4],ecx

So I still preffer "a = a + 1" for readability than "a += 1".

Point, if you are talking about me, please note that I said "in the middle of a statement". Declaring variables in areas other than the top of the function is indeed useful sometimes. But thigs like this are, I think, confusing:

for( int A = 0; A < 10; A++){...}

I rather use:

int A;
for( A = 0; A < 10; A++){...}

By the way, this just my opinion.

Topgoro


Edited by - Topgoro on July 13, 2000 5:10:49 PM

Share this post


Link to post
Share on other sites