Never trust a programmer who says he knows C++
lbrandy.com
lbrandy.com
Languages: C, Python, Haskell
Will code for food in Java,C++,C#,Whatever.
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.
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. SomeComplexObject b = new SomeComplexObject()
This should probably be SomeComplexObject* b = new SomeComplexObject()
since the former news up an object and then invokes a copy constructor before losing the original reference and leaking.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.)
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.
Less snarky: They give you evidence, really quick, that they're a 9 or 10. It's not hard to tell.
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.
virtual public setOrigin(const Point &p);
public setOrigin(float x, float y) { setOrigin(Point(x,y)); }
Someone inheriting from this class will know that all the customization is in one function.I didn't, I learned in C. I'd rather take the safe route and non-virtual by default.
What's your problem with this answer? Non-virtual methods can be easily inlined, whereas virtual methods (almost always) require:
1. a load (though a hoistable one) from the vtable
2. an indirect branch
3. register re-allocation
4. function call overhead (standard prologue/epilogue)
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.
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?
I find the inverse more interesting: Virtual by default and declaring non-virtual when the rare need arrives.
This isn't what I said, but you know that anyway.
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?
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.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.
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.
Other (shorter) commentary: http://stackoverflow.com/questions/814934/why-c-implements-m...
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.
"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.
Where do I sign?
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.
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.
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.
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)
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).
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.
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.
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.
How does this make sense?
(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."
What is this smut in my Hacker News?
source: http://www.merriam-webster.com/netdict/know
Or perhaps you meant implications of the word "know" in play? (:
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.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.
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."
Hello jrockway, nice to meet you. :)
> 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?)
If you understand those, there's a decent chance you're a real programmer rather than a language-specific programmer.