Fog Creek Software
Discussion Board




One insightful interview question

"What is your least favorite feature of the C++ language?"

I like this one a lot (at least for a C++ person).  It's open ended, there really isn't a right or wrong answer.  How someone answers will tell you something about their honesty and coding habits.  It may give you insight into whether the person is highly opinionated.

My personal answer would be "const correctness".  Other good answers might be protected/private/virtual/multiple inheritance, RTTI.  A bad answer would be "virtual functions".

How would others answer this one?  Anything in particular to look for in a candidate's answer?

Bill Carlson
Tuesday, September 10, 2002

1. That it took so long to reach an ANSI standard, and that along the way, significant milestones were not planted, like ANSI C++ 95 (a pre-templatized C++?), ANSI C++ 97 (templatized C++ w/o/ specific standard library, STL support), ...

This would have allowed compiler makers to legitimately claim compliance without the confusion as to what that really meant, and that an exception to the standard list of bugs would have meaning.

2. That constructor exceptions are difficult to code and handle properly:
http://www.awprofessional.com/meyerscddemo/DEMO/MAGAZINE/CA_FRAME.HTM

3. That assignment and copy constructors bugs are so difficult to track down that perhaps the assignment operator should never have been overloaded?

... on Software Anon: a 12 step program
Tuesday, September 10, 2002

That C++ exceptions are not statically checked, like Java exceptions. I know this is a "feature", but I still prefer checked exceptions.

Zwarm Monkey
Tuesday, September 10, 2002

I can't think of one feature I abhor, but several I would like to see.  A better macro system (like the one in Lisp), and a more fine grained access system (like Eiffel).

Multimethod support would be nice as well, but that would require a more dynamic type system.

Jay Kint
Tuesday, September 10, 2002

Pointers.

Jay Kint
Tuesday, September 10, 2002

Jay, I can sense this coming.  Bill is a macro nazi.  Whatever you do, don't mention garbage collection. 

semi
Tuesday, September 10, 2002

POINTERS!?!

<SLAP!!!>

Dunno Wair
Tuesday, September 10, 2002

Structs and classes are essentially commingled.  I'd have liked structs to be guaranteed concrete (no vtable) with classes guaranteed to have vtables (although you could derive classes from structs).  As it is, it's much more difficult to make guarantees about the underlying representation.

rwh
Tuesday, September 10, 2002

Actually, it would have to be private derivation, since the class vtable would change the struct layout.  But some sort of automated value-semantic-based wrapping would also work...

rwh
Tuesday, September 10, 2002

The lack of a decent RTTI would win my vote (the horrific hack we have does NOT count). And, as a corrollary, not having class construction by name.

The template parser. Not the concept, just how bloody badly it's been implemented by everyone. That comes in a close second.

MFC. I know it's a platform thing, but it's destroyed so much potential. So many programmers who would otherwise have been decent OO developers have been corrupted by this foulness.

ObControversiality: Const correctness rocks for finding bugs. You just have to write it in from the start and make sure all the code you depend on is right as well... I loves it, and I uses it all the time.

Katie Lucas
Tuesday, September 10, 2002

1) enums and ints are no longer the same

2) language is not stabilising but in continual process of change.

3) language designed by committee of math freaks and language theorists, not visionary individual who has experience doing programming for a living

4) operator overloading is allowed

5) C++ is a better C motto is propaganda pure and simple. Perl is a better C, not C++.

X. J. Scott
Tuesday, September 10, 2002

Oh, forgot the worse one:

0.) changes to private areas of class require recompilation of all dependents of class. Because of this, C++ can not possibly be considered to be a object-oriented language. Like, duh!

X. J. Scott
Tuesday, September 10, 2002

Oh and did I mention:

k) language's grammar has ambiguities

This is inexcusable.

Bill, this is indeed a very worthy interview question. Good insight there.

X. J. Scott
Tuesday, September 10, 2002

>> Structs and classes are essentially commingled. I'd have liked structs to be guaranteed concrete (no vtable) .

Excellent.

... on Software Anon: a 12 step program
Tuesday, September 10, 2002

"0.) changes to private areas of class require recompilation of all dependents of class"


I've managed to use the pimpl design pattern and avoid this mess (for the most part).

Which reminds me...

7)  Design patterns.

semi
Tuesday, September 10, 2002

"The lack of a decent RTTI..."

Ditto.

B
Tuesday, September 10, 2002

I always like to reply "References," to that one, because while nobody seems to BELIEVE that, there's actually a case for it. Thus it makes for interesting arguments with the interviewer.

Michael Gates
Tuesday, September 10, 2002

I thought all c++ people loved references.  I've never met any who didn't.  Maybe its a southern thang.

semi
Tuesday, September 10, 2002

Header files.

While a remnant of C, the misuse of header files has resulted in great amounts of frustration due to cyclical dependancies and scoping conflicts. Granted, these issues usually don't manifest themselves when you properly understand the language,  but the same could be said for any of the points in this thread.

Mark
Tuesday, September 10, 2002

"What is your least favorite feature of the C++ language?"

Its existence.

C fan
Tuesday, September 10, 2002

I was asked a similar question in an interview:  "If you could change one thing about Java, what would it be?"

These kinds of questions can really show if somebody knows a language that they're claiming to have expertise in.

anon
Tuesday, September 10, 2002

friend classes in C++ (or any language for that matter).

Tim
Tuesday, September 10, 2002

1) inability to declare (non-virtual) member functions of a class outside of the class declaration. A corollary of this is the inability to create efficient abstract types in C++, i.e. classes where the member data declarations are hidden from users... With today's C++ you either have to use virtual functions (and take a speed hit), or use the pimpl idiom (and take a memory/speed hit, as well as sacrificing code clarity).

2) bad standard library and STL implementations. e.g. no two releases of GNU g++ and its library are binary compatible. Object code bloat and long compilation times due to overuse of templates in STL... I experienced a 2-4X speed-up in compilation time and 2-6X reduction in object code size after switching from STL (STLport) to hand-coded containers. (which are still type-safe like STL, only most of the code is out-of-line and not templated).

Dan Maas
Wednesday, September 11, 2002

preprocessor makros

(is it spelled macros or makros in English? in German it has a 'k')

Have fun,

Jutta Jordans
Wednesday, September 11, 2002

Bad readability

Jan Derk
Wednesday, September 11, 2002

Gareat question !

Lack of a keyword to refer to base class implicitely:

  baseclass::foo(myparams);

Hence you need to know the base class name when you call it. You can't change the base class without affecting the implementation.
There are tricks (using intermediate typedefs) but if you (or the one who wrote the class) didn't follow them as of class conception, you'll have to find and replace in the implementation at least the first time you switch the base class.
Don't tell me it's because of multiple inheritance because it's not a valid point to me.

Serge Wautier
Wednesday, September 11, 2002

My least favourite C++ feature:

That there is a big committee sitting out there that is intent on adding more and more features to the language.

Beyond a certain point, every additional feature has an additional cost in terms of the learning curve for the programmer, and also the expectation that other programmers reading the code will be familiar with the latest C++ gizmo that was used there. I think C++ reached the "appropriate" level of utility a long time ago. Many of the new features do little in providing higher level abstractions that actually help you to model the problem at hand. Rather people seem to use them more because they find it fascinating, because, well that's just the way programmers are -- we have a fascination for finding clever solutions.

C++ is pretty good, really! They should know when to stop adding stuff to it.

Kaushik Sridharan
Wednesday, September 11, 2002

Lots of people with lots of insightful comments.

My least favorite feature:  Exceptions.  Reasons include:

1. The addition of this feature means that all code everywhere needs to be written with exceptions in mind, or undesirable things happen. (The most common of these things is memory leaks.)

2. Being careful in the face of exceptions usually means using the "resource acquisition is object construction" pattern. This means that you end up creating a lot of classes with uninteresting semantics, and hiding most of your program logic in their constructors. The result is far less-readable code.

3. Exceptions were a late arrival on the scene. Almost by definition, all code written before the availability of exceptions is not exception-safe. This makes it nearly impossible to correctly add code that uses exceptions to an existing pre-exception program.

4. The existence of exceptions tempts OS and runtime implementers to turn things like null pointer and wild pointer deferences into exceptions. Once they're exceptions, programmers are tempted to catch them and try to continue executing. Such catches are almost always on very shaky ground, and frequently to programs that continue to execute incorrectly, while the information needed to fix them (the state as of the time of the exception) receeds into the irretrievable past.

5. The absence of a "try ... finally" construct means that "try ... catch {cleanup; throw;}" is a common idiom. If the exception is of a sort that nobody upstream knows how to deal with, then any information about what really went wrong has been destroyed by the time that the program crashes. (The uncaught throw is the one in the outermost finalization block, not the place where the error was detected.)

Note that there *are* languages in which these problems don't exist or are minimized (Java and C# come to mind). Resource acquisition is much less of a program because the most common resource (memory) is garbage-collected. Exceptions were there from the beginning. They don't have wild pointers. They have finally clauses.

In those languages, exceptions turn into a net positive. In C++, however, they create far more grief than they cure.

Jim Lyon
Friday, September 13, 2002

> 5. The absence of a "try ... finally" construct means
> that "try ... catch {cleanup; throw;}" is a common idiom.

I miss this, too, but it may be because I was used to it in Delphi (and, later, in Java).

> If the exception is of a sort that nobody upstream knows
> how to deal with, then any information about what really
> went wrong has been destroyed by the time that the
> program crashes.

You should preserve the necessary info as you're going up the chain.

> Note that there *are* languages in which these
> problems don't exist or are minimized (Java and C# come
> to mind).

I don't know about C#, but Java does have its share of exception problems. You must be careful with exceptions occuring in catch and finally clauses. E.g., releasing a DB connection in a catch may throw an SQLException. If you don't get things right, this exception will "eat" the original exception you caught.

Another scenario is when you want to package a standard exception in a custom exception, and have a finally clause. The original (std) exception occurs, you catch it, package it, and throw it. Then, you enter the finally block, and another exception occurs. Unless you do something about it, your custom exception is gone.

I'm not saying this doesn't happen in C++, just that Java is not that problem-free, as far as exceptions are concerned.

Suravye ninto manshima taishite ("Peace favor your sword")
Paulo Caetano

Paulo Caetano
Friday, September 13, 2002

The correct answer is Complexity. C++ is too complex for the average programmer. Too complex for its own good.

Don't embrace needless complexity. Reject it.

Mr. Obvious
Friday, September 13, 2002

Hi!

Could you please let me know why "virtual functions" i a bad answer? After all, it's dynamic binding that brings in the OOness into C++.

Thanks.

Chichi
Saturday, September 14, 2002

"Could you please let me know why "virtual functions" i a bad answer? After all, it's dynamic binding that brings in the OOness into C++."

Yes, that's why it's a bad answer! C++ was designed to add OO features to C (roughly speaking), and virtual functions are one of the necessary features to do that. Saying you don't like virtual functions is like saying that you wish they could get rid of all those annoying OO-like features.

Years ago, people complained that virtual functions were inefficient because calling them involved extra overhead of looking in the function table, finding the correct function to call, etc. The point is that the benefits (dynamic binding) of virtual functions far outweigh the costs.

Adrian Gilby
Sunday, September 15, 2002

For Java... 1st order functions.  The ability to pass functions around in parameters without having to take extra lines wrapping them in some object.  A java language lawyer might say I'm passing around functions willy-nilly.  Well, I'm a WILLY-NILLY PERSON.

At least other JVM languages let you do this.  And C# has "delegates," which seem to be 1st order functions.

gringo
Monday, September 16, 2002

Hey Gringo, try out Pizza.
http://pizzacompiler.sourceforge.net/

It's 450k, but I don't think it all needs to be distributed with the app.  I haven't used it myself, so ymmv.

Sammy
Tuesday, September 17, 2002

Gringo,

You also can have a look on the language "nice" :
see http://nice.sourceforge.net/ for details.

It has 1st class anonymous functions and many more things.

Seems we need Java 3

Robert Chevallier
Tuesday, September 17, 2002

Gracias!

gringo
Tuesday, September 17, 2002

Lack of initialization for primitive types, especially in constructors.

Badly written constructors that don't initialize their variables have been the bane of my existence.  All variables, including primitive types, should have default values. 

I work on a code base where the problem got so bad that someone wrote a global operator new that callocs the necessary memory...

Greg Bronner
Thursday, September 19, 2002

> My personal answer would be "const correctness".

Mine certainly wouldn't.

> How would others answer this one?

'Modules', i.e. the way in which source code maps to file-system files.

> Anything in particular to look for in a candidate's answer?

If it agrees with (for example) Stroustrup's opinions on that topic then it's probably not a 'wrong' answer.

Christopher Wells
Friday, September 27, 2002

*  Recent Topics

*  Fog Creek Home