I've long since taken C++ off of my resume, because I haven't used it for 10+ years, since I was in school. But because I'm a normal person for a HN reader, I've kept up with the news, and in learning so many other languages at one time or another have a pretty decent idea what's going on. Recently we started hiring for a C++ position, and I was asked to sit in on the interviews. I said that I didn't really know C++, but I do know enough other stuff to keep up.
Or so I thought. Our interviewer handed out a bit of code something like this
int some_func(int, SomeComplexObject&);
.. some code context...
{
{
int a = 1;
SomeComplexObject b = new SomeComplexObject()
some_func(a, &b);
}
if (b = 0) {
cout >> "Error" >> endl;
}
}
or whatever, something like that, and asked what was wrong. People with "years of experience" in C++ would strain and strain to find "the" error. This is of course a steaming pile of errors, the only legal code line is "int a = 1;" and that's redundant (just stick the 1 in the function call).
I don't have C++ on my resume, but after that experience I'm pretty sure I could put it back on without experiencing too much flak.
On that note, if you're into languages I really recommend the C++ FAQ Lite: http://www.parashift.com/c++-faq-lite/ Anybody who can follow that should probably just leave C++ on the resume. We all know C++ is massive, this is an interesting case study in how the massive language interacts with itself.
Though the point caries, out of nerdiness, I'll point out that most lines are in fact legal:
int some_func(int, SomeComplexObject&);
Perfectly legal function declaration. You can omit variable names in the signature.
{
...
}
That defines a scope, which is also fine and occasionally used so that variable names can be recycled with other types later on.
int a = 1;
You claim this is redundant; I'm not sure why
if (b = 0) {
If there was a variable in scope named b, this would be legal (the one from above isn't), though probably not what's intended since it would always be false as it will contain the value assigned to b. This syntax is however sometimes used for things like:
if((location = find_something()) != -1) {
All of that said, if somebody claimed "years of C++ experience" and didn't immediately notice loads of errors in this in about 2 microseconds, they're either a horrible programmer or a liar, and in either case you don't want to remotely consider hiring them.
The int declaration is redundant because you turn around and use it once, then it falls out of scope so you can't use it ever again. "int some_descriptive_name = 1; somehow_use(some_descriptive_name);" would be valid and I do things like that, but not with "a". (Barring some exceptional context where "a" really is descriptive; for example, encryption algorithms following the spec closely, which is just about the only exception I'll grant to "never use lots of single-char variable names".)
Yes, if (b = 0) { is syntactically correct but the odds of you meaning it are effectively zero.
The function declaration was legal, for the purpose of highlighting the call where the & is used incorrectly. Making that illegal would significantly complexify the task of saying where the error is. Of course it's such a steaming pile that it's arguable no matter how you slice it, that's what happens when your code is semantic nonsense.
BTW, I'm just clarifying, we're pretty much in agreement, just with different emphases.
(Also, I like the cout line, now that I look at it the next day. I'm tempted to slip that in to a test somewhere. It wouldn't be a "no hire" if it was missed in an interview situation, but it would be an interesting way of seeing how detail-minded the interviewee is.)
At that time (4 years ago, last time I did a resume) C++, C and Perl. I wouldn't list Perl now. There are some other languages I've worked more with in the last couple of years that I would only mention only if they were in the "nice to have" section of a job description, and duly noted as only "some familiarity with".
I have three standard "screener" questions: (a) what's a virtual method, (b) why would you want to have a destructor be virtual, and (c) what's a virtual base class.
Most folks (if they have a head on their shoulders) get A, a lot get B, and C befuddles almost everyone. (There are a few situations where you'd want to use a virtual base class. And if someone replies, "Oh yeah! I use those all the time!" they're probably using /other/ parts of the language that are just as unsavory).
Related to the original discussion: I've found the folks who self-rate themselves (on a scale of 1-10) as nines (and one guy was a ten) are generally bozos. This is independent of the language in question.
I've been using C++ as my primary language for the last 10 years and know what virtual base classes are. I would never use them, Instead I'd avoid diamond inheritance at all costs.
I'd rate myself as a 9 or 10 for language proficiency but perhaps not for certain niches. For example I know comparably little about Win32 or COM (ugh).
However, there are tons of programmers out there who can't program. Faced with a clean slate they would either choke or create an atrocity. If they rated themselves 5/10 then for me to rate myself only 8/10 would be a disservice to myself. The same is true of perhaps 90% of the programmers on HN.
Of course, I can look back at my former self and know that he thought he was awesome but clearly I have surpassed his ability. It only makes sense that there are far greater programmers out there and I have met a few.
Right. The bit about virtual base classes is to simultaneously find the folks who know what it is, and to get a good feel for their design sense.
"Don't know" is okay, if they're otherwise a strong engineer. "Love them!" is only good if they can justify it. "Yeah, diamond inheritance, avoid that" is pretty much what I'm looking for, though I'm willing to have a serious conversation about their merit.
These are just questions I can get through in a minute or two, to gauge the person quickly.
I have a more in-depth paper that was rejected last year which I'm trying to extend right now. If you'd like to read it, you can. I have another paper under review that uses my work to make a Cell, GPU and Quad Core performance comparison.
I used to think a good C++ screener question might be: "When would you use the 'nothrow' constant, and when would you have empty 'throws' specifications in method declarations?"
But then I realized this is just getting tricky with C++ arcana, and is unfair. I once read all of Herb Sutter's 'Exceptional C++' series, and they scared me so much that I still get the frights, years on, when contemplating approaching a C++ compiler.
And I used to think I was OK with C++ too. But after Sutter's books I had to accept that, nah, at best I was mediocre. I admire people who can boldly cast out and rapidly prototype a library or something. Or who have the patience to iteratively engineer a Boost library. I will never achieve this, despite once desperately wanting too.
So you're asking for OOP, no generic programming / templates? I know template metaprogramming magic becomes madness real fast :-)
I tend not to ask direct language questions anymore, everything is related to the code written on the interview. Like, you asked for a function doing something with an array of ints, and when you get the code you say "now, can we have this function work with arbitrary types instead of just int", "what are the constraints about this types", "what happens if it has a copy constructor but no assignment operator" etc.
And I accept everyone knows and uses some subset of the language.
A better question is: Why do we need to put the archaic virtual keyword in front of a method? Shouldn't non-virtual functions used in an inheritence way be declared as private while the other being automatically virtual ?
Then if he agrees, he's ok. If he gives you more examples of why C++ is archaic, he's great. If he begins talking about non-virtual methods being more optimized than virtual one, thanks him for his time and try to find someone else.
What if he makes a case for keeping types as POD when possible? :)
Anyway, it is clear from your comment that you dislike C++ and you prefer to hire people who agree with you that C++ is archaic, that is fine and all, but it doesn’t show in-depth understanding of the language. Explaining why things are as they are does show deep understanding of the language and a desire to learn the dirty details, IMHO a valuable trait.
It's a way to avoid a 100% only (and closed mind) C++ programmer. Understanding the cost of a virtual function is something. Not understanding that in most situation this cost is trivial, is something else. And every C++ great programmer should know that C++ is archaic and that higher level languages exist. If someone only knows C++, he is a C++ programmer, not a programmer.
Virtual functions are helpful only when you have derivation and need some common interface. When your class is not meant to be derived from, declaring functions as virtual is just plain misleading. And I am strongly against fitting everything artificially into a class hierarchy, that is, I dislike using the OOP sledgehammer for every simple class.
Also, great C++ programmers are those who use C++ in a problem domain matched to it, not those who use C++ where Perl or Python or something else is so much better. So they know that C++ is not archaic at all, it is just not suitable for every job, but then, what language is?
IMO, you shouldn't dismiss a candidate as close minded with one question. If you have fears that he only knows C++ and doesn't care about higher level languages, you should digg into that with other questions.
C++ is used in places other than bleeding edge PCs, you know. The impact of a virtual function call is non-trivial on some systems, the most prominent one that springs to mind is the PlayStation 2. Knowing how they work and when to use them is always a good thing. With that sort of attitude you'll only hire people less competent than yourself; you're trying to find more competent people.
Thanks for saying I'm not competent. First, I know what a virtual function is and how performance might be important. However, it's just illogical to use inheritences and OO without using virtual function. Just think about the virtual destructor.. why isn't it automatically virtual?
I find the inverse more interesting: Virtual by default and declaring non-virtual when the rare need arrives.
Just think about the virtual destructor.. why isn't it automatically virtual?
Basically, because not every class is used polymorphically, many are designed to be used primarily on the stack or as members. The merits of what should be the default are debatable, but as with anything in C++, the reason is probably historical. For example, it would break all C code that used structs. One of the C++ design principles is to not impose features upon you that you don't need, so that might be why they decided not to e.g. make classes have virtual functions by default, but not structs, a bit like classes have private members and bases by default.
In any case, these are straw man arguments. The point I was trying to make is that you suggested turning down people because they know the low-level details of the platform and their implications. I counter that this is a phenomenally bad idea; knowing what lies beneath the abstraction is always a good idea, especially if that reveals dragons.
You haven't said anything to counter that, instead pointing out aspects of C++ you don't like. If you dislike C++ enough not to use it, why are you interviewing people for C++ programming positions anyway?
You are right that knowning low-level detail of a language is great and I have badly explained what I meant to say in my first post (Mostly because I'm a terribly bad english speaker). Here is what I meant to say: C++ is archaic for a lot of reasons; just read effective C++ of any book and you'll find subtile bugs that you need to avoid.
My point is: I don't say whether C++ is bad or not but when you compare it to scheme or python, for instance, you clearly see that there're some archaic parts. Some programmers only know C++ and have closed mind on everything else. If they start arguing about the glory of those "c++ design error", it's a huge hint that it's a C++-only programmer.
OK, I'll quite happily agree with that. I'm generally wary of people who won't venture outside one language (one-trick ponies). I personally try to avoid using C++ except where it's clearly the best choice, mostly because I used it as my main language for the best part of a decade (high performance computing and game development). The thing is, C++ is still possibly the best choice in that narrow segment where C alone is too tedious but a high-level language won't work for some reason.
Basically, because not every class is used polymorphically, many are designed to be used primarily on the stack or as members.
I also see classes used as members in Smalltalk. I wonder if a language can make the use of these sorts of objects explicit? Seems like there should be a good opportunity for better optimization.
A a;
A* p = new A;
assert(sizeof(*p) == sizeof(a));
This wouldn't be true and cause all sorts of trouble (arrays, etc.) if a had no pointer to a vtable, but *p did. Moreover, you can take the address of a stack/member object, so how would you distinguish the two types? You'd literally need to modify the type system, and that would cause trouble with templates, etc.
Modern C++ rarely use subclassing¹. The default in my code should certainly be non-virtual.
Someone already mentioned the performance issue. This applies both to run-time but also memory. Imagine we introduce a new type called ‘point’ representing a 2D point. We may have millions of these and we may store them in vectors, here we do not want to pay for the memory overhead of adding a jump table to each point in this vector (or initializing such pointer when constructing points, going through the jump table when doing “simple” math with the points etc.).
¹ Although the substitute for subclassing to achieve polymorphism in C++ tend to be generic programming, many OO languages are advocating composition over inheritance.
That is only a problem if and only if that method is being called in a very tight loop and its body is not particularly time consuming. A person making optimisations like this without first timing the code or at the very least spending some time introspecting on the pros and cons of doing so would not be someone I wanted to work with!
One of the main design principles behind C++ was "you don't pay for what you don't use." Hence, if you don't want to use polymorhpic member functions, then you don't pay for the overhead.
> Anybody who says they are good at C++ is either delusional or has spent years writing, linking, debugging it.
This strikes me as a completely reasonable and not deprecating thing to say about any powerful language (such as C) or any advanced tool in any profession for that matter.
I'll speak about my two main sharp instruments these days: C and Python. IMO, it doesn't take years to get "good" at these languages (C, because it's a smallish language; Python because it tends to obey the principle of least surprise fairly often). With sufficiently deliberate study, I think it'd be fair to call oneself "good" at either C or Python after a single year.
I suppose I probably ought to clarify what I mean by that. I mean that someone "good" at C or Python is someone who's made it over all of the typical newbie hurdles and is able to spot typical newbie mistakes more or less at a glance. This is not someone I'd expect to have total control or mastery over the language or to know the respective standard libraries inside and out.
Now, to become an expert in either of them, then, sure, you're going to need many years of experience (and, if you want to claim to be a Python expert, you need to be at least "good" at C, IMO, because there are times when you're just going to need to suck it up and write a C extension).
Badly standardized? Not since the mid-90's. And the days of cross-compiler pain went away almost completely when the last big holdout of the pre-standard days, Microsoft, finally released their 2003 C++ compiler.
Your next point, that C++ is just C "with OO" strikes me as deeply ignorant. OO is an important feature, but 95% of the language innovation of the last 20 years has been in templates.
Compilation errors are a pain in C++. It's something that takes months for a smart programmer to figure out. Debugging C++ is harder than debugging C, yes. It's a more complex beast.
Reading your post I get the impression of someone who has read a lot more about C++ than working with C++. Try interacting with any modern C++ code-base (something written in the last 10 years), avoiding the template meta-programming code-bases which are really only of use for library-writers not library-users.
Hey, I'm programming in C++ right now. It's the worst language there is except for the all others (to paraphrase Churchill on democracy). I'm glad to see someone can say something good about it.
I'd also rather be programming in c++ than rating myself in c++ or any other language. The whole experience of being asked to pick a number for your skill level is truly annoying.
Another post that confuses "all the features of C++" with "programming in C++"
Once more for the record, programming in C++ does not involve using all of the features of this massive language. In fact, a good C++ programmer keeps things as brutally simple as possible. C++ programming forces you to.
The author is dead-on about how you get swamped by the features. What he missed is that you come out of the valley on the other side with a good appreciation for "That hurts. Let's not do that unless we absolutely have to"
You know, C++ has to be a significant language. Nowhere else have so many people cried out in pain and frustration. Yet the language still rolls on. That's probably not much of an endorsement! (grin)
I mostly agree with you but I don't think I'd apply for a job specifically programming in C++ without knowing the appropriate use cases for the majority of the language features. Obviously different if you are only listing it as a language you have some familiarity with.
I think you overestimate the value and difficulty in learning the less often used aspects of C++. C++ still includes the asm keyword and in some areas you are going to see it used. However, while I might like people to know at least one ASM language it's far from required to call yourself a C++ programmer.
I would still expect a C++ programmer to know when assembly might be used (i.e. the use cases, the benefits, the drawbacks and the alternatives). Admittedly, I'd also expect them to know it really isn't an area they should mess with unless they really have to.
Never trust a programmer who says he knows C++...
Never trust someone who says he knows...
Never trust a programmer...
Never trust C++ ...
Never C++...
At university, they taught me C++. I suffered a lot. So the minute I graduated, I stopped doing it. This was a valuable lesson after all.
If someone pretends to understand C++, just look at his code and say "Ok, so what happens if you add 'volatile' just here."
The underling effect of volatile is that the compiler turns off certain optimisations to do with instruction reordering and aggressive caching in registers without stores.
However in most places that a typical non-firmware, non-driver programmer would use volatile they really should be using a memory fence (acquire, release or atomic store).
I have a hard time with names; I generally think of this as "the third quartile effect". Most people self-evaluate themselves as being in the third quartile of ability - the lowest fifty percent overestimate their ability, while the highest quartile tend to underestimate themselves.
1) There are a lot of nooks and crannies that can bite you in the butt
2) It's cosmetically similar to C and Java so you get a false sense of security (The article points this out).
3) It's popular (same effect for PHP or Java (I took a intro to programming in this language, so I know it!))
4) Due to #1, every decent C++ shop tends to standardize on a subset of the language, with practices that deal with the nooks and crannies of just that subset.
In my current free time project, I learned enough C++ by reading assembly to not find anything new in Lippman's "C++ Object Model". I'm not sure if that's a good sign or a bad one - did I see so many tricks, was I not reading attentively, or what... pity the book doesn't cover COM+ though.
When I inherited this project, it was relying on (cast)s and macros all around and this led me to some nasty traps, I switched to building a lot of templates, they've so far proven invaluable in saving debugging time, enforcing type safety, and communicating expected data types to other developers. Templates are good. And macros are traps, but everyone already knew that.
Granted, the project is a niche, I don't think there are many similar projects out there, so not sure how useful my knowledge of the object model is. I'm reversing/extending a C++ game with no source, btw. DLL injection and all that goodness.
Odds are, one should never trust a programmer who thinks they know [X]. Odds are they only think they know really know [X], but they haven't gone too much farther than figuring out how to use the library.
Amen to that. It's always amazed me how many candidates I've had sputter on something like this. Nothing flips my bozo bit faster than someone claiming a particular language or technology they've supposedly "mastered" is perfect.
I worked at a shop with a supposedly Object Oriented architecture. However, one subsystem consisted entirely of Class methods -- very, very long class-side methods with nested loops, deeply nested logic, and a half dozen array simultaneously incremented indexes that recursively called cut-and-paste variant copies of themselves.
Now I work with a different company, but I was interviewing someone who worked at the same shop, and asked him about his opinion of the architecture of the above subsystem. His answer: "It's very nice."
I've started asking in interviews what people thought was wrong with a particular language or environment and if they had any thoughts as to features they would want added (or removed).
That reminds me of an interview I did years ago with a Computer Science grad student. His area of study was in compilers, and he said his strongest language was C.
So, I asked him: "what would you improve in C? What's less than ideal about it?" He couldn't tell me a single thing.
EDIT: This comment literally says "usually if you think you know something, you don't." So I guess I shouldn't apply for a job using language FooBar, since by this guy's rule I probably don't actually know FooBar.
Yes, exactly! I didn't become the half-decent programmer that I am until I finally embraced the fact that my code sucks and adopted highly defensive coding practices as a result.
Well, the only (literal) meaning of "know" that doesn't fit what everyone else on this thread was thinking it meant is:
(3) archaic : to have sexual intercourse with
So we should rephrase
"Odds are, one should never trust a programmer who thinks they know [X]. Odds are they only think they know really know [X], but they haven't gone too much farther than figuring out how to use the library."
With something along the lines of
"Odds are, one should never trust a programmer who thinks they have had sex with [X]. Odds are they only think they have had sex with really have had sex with [X], but they haven't gone too much farther than figuring out how to use the library."
Note the comment makes no absolute statement. Note the reference to "odds." This is almost the same idea as: "Remember, most people think they're an above average driver. Also remember, half the people are below average drivers."
It's also along the same lines as, "There's always someone better than you."
Also note the use of "really." "Know" is twice accompanied by the adjective "really." I would've thought this would make it clear that I wasn't talking about "a little knowledge." The odds are that a programmer does have "a little knowledge" about [X].
Given that you, despite claiming to be puzzled didn't try to take "odds" or the frequent use of the adjective into account, I wonder if you are apt to catch details like that. Maybe this would make a good interview question for coders?
Also remember, half the people are below average drivers.
Depends on what you mean by "average". If you mean "median" you are correct, but if you mean "mean" (like most people do) this is not necessarily true for most interesting situations.
I have never met anyone who knows C++. I have also never met a C++ programmer that knew how to program or what OOP was. (Polymorphism? What's that? Tests? What are those?)
Sounds like you've just met a lot of bad C++ programmers. Given that most programmers are terrible and there are a LOT of people who claim to be "C++ programmers", I guess that isn't too surprising. People who actually know (sane, modern) C++ are rare.
I'll be upfront in admitting that I loathe C++ just as much the next guy (I can't seem to get away from Lispy languages), but isn't this being a teeny bit ridiculous?