tags:

views:

1511

answers:

25

Either due to lack of knowledge, fear, or first-hand experience (getting burned) and saying "You know what, just because it's in the language, you don't have to use it."

Quoting Chris Rock: "You can drive a car with your feet, but that doesn't mean it's to be done!"

What's the C++ equivalent of driving a car with your feet?

+19  A: 

I've never used and never will use goto. Apart from the standard "why goto is bad" debates, the most compelling reason is that it leads to debates.

Ates Goral
yeah -- you are going to have to defend it -- agreed.
Lou Franco
i disagree with this reasoning in general, the fact that it 'leads to debates'. With that logic you wouldn't use tons of features that are actually useful.
Claudiu
Yeah, but the debates for goto are so old and repeated that it just isn't worth it any more. For new stuff -- sure, have new arguments and figure it out -- for goto, I really don't want to deal.
Lou Franco
Using goto is the only way to remove recursion from some algorithms
crashmstr
"Never" is such a strong word. You should be more open-minded -- there may be times when a goto is the correct solution, even if it usually isn't.
Adam Rosenfield
In twenty-two years of C and C++ programming, I've used goto exactly twice, both times because it was a cleaner solution than any of the alternatives.
Head Geek
I just posted a blog post about this topic - http://shadowcoding.blogspot.com/2008/10/hatin-on-goto.html
Erik Forbes
Just the fact that my comment has generated a mini-debate here supports my point :) I think this comic pretty much sums it up, and actually has a very deep meaning: http://xkcd.com/292/
Ates Goral
If only premature optimization led to the same debates.... "It is bad!" "Not in this case." "prove it." " it is a hypothesis; show me profiler output" "uhh..."
ejgottl
MISRA C++ explicitly allows goto to jump to an enclosing block further down the function body. Back jumps are dissallowed, and jumps into scopes.
Richard Corden
this is not a C++ feature in the sense that other languages (like C) do not provide the same!
Matt Joiner
+8  A: 

For me it kind of depends on who the other coders on the project are and what the benefit of using the feature is.

The easiest way I find of tripping yourself up is making object ownership too complicated -- meaning that it's unclear who deletes what. In that sense -- holding onto pointers to member functions can sometimes be bad if it confuses people about how many referrers there are.

Lou Franco
The issue of who owns what is an issue for almost any language, even those which have Garbage Collection.
OJ
Smart pointers were designed for exactly this reason. The last one to use an object deletes it.
coppro
Smart pointers usually can't deal with references held by method pointers. Also, you can't solve every ownership problem with smart pointer (circular references, 3 party interfaces)
Lou Franco
+5  A: 

IOStreams (slightly embarrased) and especially stringstream I mostly do GUIs anyway and if I need to print something I think (s)prinft() is perfectly fine and a lot cleaner to read ( I do admit that << is safer)

Martin Beckett
I find the new I/O stuff doesn't have as good error reporting. Good old errno.
Lou Franco
Also, format strings ("%s %d %lld") can be resources, but code that uses iostream to format its output must be recompiled.
dicroce
For mixing format strings and iostreams, you can use boost::format. :-)
Chris Jester-Young
stuff using boost, it's all that's evil about c++ in a single library
Matt Joiner
+5  A: 

I've never used longjmp in C++. Other than that, I've used almost everything (that I know about) at one time or another.

ejgottl
longjmp is for C. If you want this functionality in C++ use Exceptions with try/catch.
OJ
Yes. But it is in C++ as well, as are many legacy C features. This is the only one that I could think of which I had never used (aside from trying to compile C code with a C++ compiler) for the good reason that it is not guaranteed (by the standard) to actually work with objects on the stack.
ejgottl
Has anyone ever justifiably used longjmp?
Martin Beckett
@mgb: I have used longjump to emulate exceptions in C.
Zifre
never ever had to use it. it sounds infinitely better than exceptions too :)
Matt Joiner
+8  A: 

I rarely use these:

goto because it's usually emblematic of poor design on my part

RTTI because I've never really had a driving need for it(and it adds ineffiencies).

const_cast because constant values tend to stay constant in my code.

Paul Nathan
If you only had the RTII comment I would downvote as I use RTII and find it useful But I totally agree with you other points :)
nlaq
Well, I've never had a driving need for RTTI. It's not that I avoid it. I think it's pretty cool, tbh.
Paul Nathan
goto has its place. Sometimes it's better to just 'goto' than setting a flag and doing a compare and branch within a loop.
spoulson
There is one valid use for const_cast as illustrated in Scott Meyers' Effective C++. You can use it to forward a call from a non-const member function into a const one, then cast the return. This is for when your function is identical to the const one, except the return value is const.
coppro
There is actually one more valid use for const_cast: For interacting with legacy APIs, like Win32, where you present a const correct facade but internally needs to const_cast.
Johann Gerell
@coppro: Meyers's pattern has a weakness, though, that if the const version is non-trivial, and calls something that *always* returns const (or is later changed to), then you get undefined behaviour and no compiler warnings. If the const version is trivial, then there's no harm in code duplication.
Steve Jessop
+1, Need for RTTI is usually a sign of bad design
abababa22
Agreed! These features have their place, but it's usually in a sticky one.
Matt Joiner
+4  A: 

Things I would avoid, in no particular order:

  • 'goto' (for obvious reasons)
  • inline assembly (for hopefully obvious reasons)
  • overuse of boost, especially in interfaces other programmers will use
  • multiple inheritance, not because it doesn't work, but it's hard to get right
  • overloading standard operators to do non-obvious things

Things I don't use, but not because I dislike them:

  • STL objects (I use MFC classes for most standard things)
Nick
MFC and standard in the same sentence, wow :-)
Martin York
MFC, gross man, props for the rest.
Matt Joiner
+6  A: 

Multiple inheritance - Unless you only have one Class and the rest are abstract classes.

Multiple inheritance causes many many many headaches.

nlaq
Really? The only time MI causes a big headache is when you have a name collision or a diamond. With a diamond, you should try using virtual inheritance (in many cases, the diamond is accidental and the cost of virtual inheritance is only 4 bytes). And restricting to abstracts doesn't actually help.
coppro
Nah, MI is awesome. :)
Paul Nathan
Reminds me of that class for which the best design was a template class multiple inheriting from two (non-template) interfaces.
QBziZ
+16  A: 

"Creative" overloading of standard operators can appear useful at first glance but can turn into a huge pain. Standard operators should keep doing what they would normally do.

Along those lines, implicit conversion operators are often a really bad idea when it comes to maintenance. Maybe your WidgetFrobber class can sensibly be turned into a string or an int*, but that doesn't mean it should be implicitly convertible. Provide a ToString() or a ToPointer() method if you need to do that - don't add an operator int*().

Charlie
+1: Agreed. I got bit by that a while ago. Was a real pain.
Paul Nathan
+21  A: 

This is a bit different than a lot of the other answers, and in some sense it's not exactly a feature, but I avoid manual resource management. Manually freeing memory rather than using auto_ptr or shared_ptr, or manually releasing COM interfaces rather than using CComPtr. Sure, you can manage resources yourself, but that doesn't mean you should.

You could call it the "C++ can be written just like C" feature. Bad news.

Charlie
+9  A: 

STL algorithms and function objects. While they're a cool idea, and certainly work effectively, it almost always seems to work out that I can do the same thing with a loop with much less code.

Jason Etheridge
I have to agree with this. I can spend 15 minutes putting together a bunch of nested functors to express the operation I'm trying to do (usually involving bind1st/2nd and mem_fun), but the result is so opaque. The loop is clearer.
camh
I hear this argument usually from people who are not used to using the STL. Once you can use it, the code becomes much easier to read as every iteration usually has a really meaningful Ftor name, eg. FindNameInSet.
Richard Corden
I agree with Jason for std::for_each. And I have yet to dihest bind. Still, I see a lot of "hand-coded" algorithm supposed to be faster, clearer, better than their STL counterparts, and which are just a bundle of poor quality code lines put together by a "C+" developer unwilling to learn C++.
paercebal
jdt141
Downvoted. If you feel so strongly about this, post some examples.
Nick Presta
I've been using C++ for over 2 years now (not long I know), but I find iterators only suffice for the simple cases. As soon as you begin to do things with multiple containers, or iterate in unusual ways, the tiny bit of safety that iterators provides is lost. Iterators give you 2 points of complexity for 1 point of safety. Additionally, many other languages suffer from problems with iterators, albeit they're not near as nasty as in C++.
Matt Joiner
-1,Using the algorithms effectively requires knowing what you are doing.
lsalamon
+6  A: 

I don't think there's any feature that I would deliberately avoid. I think it's more about choosing which features to use with care, making sure that they work together to towards a good, clean solution. Even the best features of C++ can be abused.

There are features that I've never used, such as RTTI. That's doesn't mean I would never use it. It just means that, so far, it has not been necessary for me to use it.

EDIT: I don't use exception specifications. I thought they are going to be deprecated in C++0x.

Ferruccio
+7  A: 

Template's are great, when used judiciously, but I think template meta programming is the spawn of the devil.

dicroce
Template meta programming is only bad because of the errors compilers generate. If the messages were clearer then it wouldn't be such an issue. Fortunately, C++0x is going to help with that.
The messages aren't that bad if you treat them like stack traces and work your way back from the last part of the message forward.
Ferruccio
@Ferruccio - that's still quite bad. If I wanted all my errors in the form of stack traces then I wouldn't be using a typed compiled language in the first place. TMP is a scripting language, and the "compiler" is acting as an interpreter. With no debugger ;-p
Steve Jessop
all to generate values that should have just been constants.
dicroce
+2  A: 

I don't avoid anything that's a standard feature. There are some (like macros and arrays) that I won't frequently use, but I use every part of the language, including exception specifications and locales, which are both (in my opinion) vastly underused. Exception specifications are not as powerful as they are in Java, but they can cause a call to a function of your choice, which can do something useful like print a backtrace at the point of the violation.

I also try to use Boost whenever possible, since I consider it to be the standard library's little brother.

Actually, there is one feature I never use, and that's export. But were it implemented to a useful degree in compilers, I probably would. Unfortunately, it isn't, so I won't use it.

EDIT: Alright, I won't use some legacy C library features like longjmp or varargs either. But they don't tend to work that well in C++ anyway.

coppro
varargs works perfectly well with C++. Just... not with all aspects of it.
Tom
+3  A: 

Lately I've been learning to use polymorphism to avoid switch. In many places a huge switch statement used to determine what derived class an object is can be replaced with a virtual function call.

da_code_monkey
lol. every c++ programmer jumps on this. be careful, as it may eventually catch you in the dark.
Matt Joiner
A: 

There is an excellent list of frequently questioned answers that has a detailed enumeration of all the things in C++ that you probably shouldn't use.

Glyph
Summary for those who can't be bothered reading the site: "all of C++". It's quite entertaining, though.
Steve Jessop
+12  A: 

Oddly, enough.... pointers.

With std::vector<> and std::string, there's really little need for them. The few that are left are squirreled away in a class, with a new in the ctor and the delete in the dtor.

James Curran
I was going to say that.
Konrad Rudolph
Now that you mention it, me two. References also help to avoid them.
Martin York
that's ridiculous. pointers are an absolute necessity to a language like C++. in fact one of the biggest problems with c++ is the lack of specialized pointer containers, take a look at flyweights for example. also no pointers means terrible performance. this is simply not an option for C++ if it wants to maintain it's niche!
Matt Joiner
I would give +2 if I could.
DevSolar
Pointers are critical to polymorphism and many other designs. Qt is based directly on pointers, and removing pointers is totally impossible without breaking the underlying PLATFORM. You won't be able to call ANY OS API function without pointers.Oh and, references are probably implemented as pointers in the compiler. Same for iterators, they can easily be pointers.
iconiK
James Curran
+6  A: 

Overloading new and delete operators.

I accept that it can be useful on some cases, but I can not risk having different behaviors when using different compilers or different platforms.

+4  A: 
  1. Global and static variables unless there're good reasons for them to be singletons. They're my pet peeves in multi-threaded code.
  2. Explicit lock/unlock, malloc/free, new/delete in application code. Use RAII.
  3. Your own stuff in global namespace. Proper namespace usage is mandatory in production code.
  4. Protected data members. It will prevent you from using composite patterns easily. Always use protected member functions whenever you need protected access. Public data members however are often useful as part of the API.

I pretty much use everything else mostly via boost and STL :). I've needed setjmp/longjmp to implement resume in test code to check exactly how many SIGABRT/SIGSEGV/SIGBUS are received. I personally never needed goto and fall through switches but I've seen nice code that use them and certain wouldn't avoid them when needed.

ididak
+3  A: 
  1. RTTI, because it is never really the right design for me

  2. virtual base classes. Has anybody used this for more than a sample in a programming tutorial?

  3. Exception specifications. They don't work the right way.

On the other side, I do use inline assembler, goto, multiple inheritance when appropriate.

Christopher
Eh. If you've done any sort of modular programming project, you can't do it without virtual base classes.Also, boo hiss at inline assembler and goto :)
GMan
A: 
  • goto / labels
  • volatile (never had a need)
  • const_cast (const is const in my code)
  • probably some preprocessor tricks (I limit myself to header guardians and includes)

I never tried writing my own memory allocator for STL container, probably I don't belive I can beet the guys that wrote my STL implementation.

Second thing that's on my list is writing my own STL container so all iterators / algorithms from STL works with it.

Nazgob
+3  A: 

Avoid exception specification which does not work as you may expect. Herb Sutter explains you why in the article "A Pragmatic Look at Exception Specifications"

Nicola Bonelli
+4  A: 

All the junk inherited from C :)

Anders Rune Jensen
If I was an ass, I would post an answer saying "All the junk Stroustrup tacked on." But someone already basically did that for me.
Chris Lutz
Must be tough to write a C++ program without `#include`.
dan04
+1  A: 

I avoid anything I'm not good enough in to keep my feet bulletproof. The top of the list would be: templates meta programming as a whole, multiple inheritance and polymorhism. Yes, each of this features may save me a bit of time while implementing somethins in C++ code, but I need to spend a lot of time to study them in the first place. I do learn new stuff little by little, so maybe I won't avoid some of this features in a future. For now I can get my work done with the skills I allready have, and I'm not getting paid for toying with languages cool stuff.

akalenuk
A: 

Speaking from the context of a C programmer, who at times has been thrust into the postion of trying to understand others c++ code, here are some things I would recommend not doing:

  1. operator overloading
  2. multiple inheritance

yeah it may inhibit object orientation, but my experience is that these features encourage excess unneeded object orientation which in turn makes for very difficult to understand code.

loneRanger
No operator overloading? Do you mean things like "Vector a,b,c; a = b + c"?Because I hope you don't prefer "Vector a,b,c; Vector_add(b,c, "
GMan
Tom
+1  A: 

I avoid the export keyword because of its (non-existent) implementation of most compilers.

vobject