Never trust a programmer who says they know C++
lbrandy.com
lbrandy.com
Obviously very few people, possibly none, know 100% of all possible knowledge (how various compilers work, all possible UB, gotchas of stdlib, patterns to use to avoid bad things) to be known about C++. Congratulations to you if you are able to find an example of something someone who “knows C++” does not know. But nobody claiming to know C++ is claiming to know 100% about it anyway, it’s obviously a way to phrase that you’re familiar with it and competent enough with it to be productive based on experience and exposure.
You wouldn’t hold a programmer in other languages to the same standard. Most people who “know Java” aren’t JVM hackers, most people who “know JavaScript” aren’t familiar with all the actual details of how JavaScript gets interpreted and executed by the browser, or how V8 works.
Yes, the main difference is that it can be easier to introduce certain classes of bugs in C++ than in other languages. You don’t need to know 100% of C++ to know it well enough to mostly avoid these. Buffer overflow, memory leaks, and UB are all something a person who “knows C++” is able to avoid by conforming to common patterns that limit the use of features leading to this behavior/structurally avoid them. Stop being pedantic
I think the point is that almost nobody can say they "know" C++ in this sense. You have to be more specific -- what parts of C++ do you know well enough to claim competency? It's probably not all of it.
It’s not wrong or misleading to claim you are eg a cancer researcher or study English literature while not knowing all cancer research topics or all works from all niches of English literature. Because everybody who works in those areas knows that it’s implied you were exposed to only a limited subset. If laypeople assume that “knowing” a broad and complex thing means you have 100% of knowledge across the entire domain, that’s a problem with their interpretation of the claim.
True, but also cancer researchers and Eng Lit professors would never say they "know" cancer or English literature. They'd say what portion of those topics they know.
Also, a big part of the problem is that you really can "know" most languages in their entirety at a competent level. C++ is unusual in that you can't really do this with it. So assuming that "know" means "truly expert in" is not really a ridiculous thing to do if you yourself aren't very familiar with C++.
When someone says they “know” some other language, it’s rarely all of it either.
Take Python for example, I know some very good Python programmers who have been using the language for 20 years and yet wouldn’t claim they know every single feature, dunder method and standard library feature, but would absolutely say (rightly) that they know python.
I’d be warier about someone claiming to know all the C++ features without having a lot of experience maintaining it or running it at scale, than someone who claims to know less features but has maintained it and ran it at scale. It’s very much a language where you need to be humble about what you don’t know and careful about introducing things you don’t understand well.
I think this “use what you know” is actually true in most languages including Java and Javascript, it’s just that the failure modes usually manifest as poor performance rather than unexpected semantics like in C++.
When you are writing "real" programs, not just "leetcode solutions" you will come across all the myriad ways that c++ is fucked up.
But as someone who has been primarily working with C++ (14,17,20) for several years I will continue to colloquially simplify that as “knowing C++” while having the humility to note that does not mean I know nearly everything about it. I know how to prevent subtleties and unexpected outcomes reasonably well within the subset that I commonly work with, and also know that when working outside that subset or using things I don’t understand well, that I’m wielding a footgun that must be treated with extreme caution. And most people who “know C++” would also be in that camp, and we’d know that’s what each other means when we say we “know C++”
This actually happened where I was trying to fix 1 thing but another entirely different thing broke and no one knows why. So I just leave the PR to rot. I was only 1 or 2 years into C++ at this point and I already know at that point that I don't think this shit is viable at all. I mean half of C++ talks/discussions is fixing itself, not actual real world problem.
I think you are underestimating what you know and overestimating what the average people know. I have seen interviews where there is a very large gap of knowledge but they don't seem to know that its there. It seems to me that the general population's idea of C++ is very different than those that talk and use it a lot.
Having said that, there are definitely "gotchas" that trip people up, but honestly, the biggest problems I've seen is people have a poor understanding of object-oriented analysis and design. Plus I'd love to get back all those hours of people arguing over whether methods should be private or protected, or virtual, and whatnot.
It took the industry a long time to figure out the best practices and by the time those emerged a lot of bad habits had been formed. That's the biggest advantage Rust has - they started with a clean slate after the best practices had been learned. C++ needs to maintain backward compatibility and as such, it's quite a complicated language. But not so complicated it can't be learned. It just requires more effort than most other languages.
We used lots of C++, Objective-C and even Objective C++ (g++ mixing Objective-C + C++, connecting to C++ engine) in a custom game engine that worked on mobile for lots of shipped titles. It is powerful and fun. I have 5-6 years using it everyday across games and media apps, bits across the rest of years, but so much territory uncharted.
I actually like C++ but it is like a lightsaber, it can be dangerous. Most apps still run on C++ at some level, even virtual machines. C++ is the stick shift manual transmission of programming languages. I'd build more in it beyond games if allowed and use it on personal things quite a bit.
In my opinion, if you can work daily in C++ for some years that all other languages are easier from there. The understanding of the machine is better from memory to stack/heap to performance, cpu/gpu bounding, networking, and the sheer power of the root of all applications. C/C++ are where the machine meet code just above assembly, there is maneuverability there but also danger.
Fun fact: Objective-C was created before C++. Objective-C all they way back to 1981 but officially 1984. [1] C++ all the way back to 1982 but officially 1985. [2]
Obj-C and C++ are really very different, so it makes sense to use each one for what it's best at; and the syntax of each is so different that it clashes much less than you'd expect.
The game engine is in C++ so to use it on iOS we needed to have an integration point for the system level Objective-C libraries to the C++ game engine (same with Android NDK integration in a way).
Another game engine from around the time Oolong Engine [1] also used this and was used for an early Quake to iOS port.
Like our custom engine Oolong used PowerVR/PVRTexTool to simulate PVRTC/PVRTC2 textures.
This setup made it so you could just develop your whole desktop/console/mobile game on PC then it would run on iOS with the Objective-C++ integration points. That was huge for game studios that only had PCs pretty much at the time.
It's pretty great for the reasons you said.
Also the amount of template voodoo necessary for certain things to be ergonomic to use is insane at times.
/rant off
It was cursed: once picked up it couldn’t be put down. It was also very powerful, with only one downside: randomly you’d hit an ally in the same room instead of the enemy.
Reminds me of a lot of things in the world.
It was also just at the right level that you’d be getting self-confident and even a bit cocky, but not experienced enough to recognise such an obvious trap.
Of course, I dual-wielded two of them like a maniac to the dismay of my party. I only killed a few allies! An accident, I swear. Not my fault.
Saeed [grinning and pulling out knife]: Now that we have the Control agents, they're at our mercy.
Abdul: Put your knife back in its scabbard, Saeed! I've got other plans for Agent 99 and Maxwell Smart!
Ssshhhhrrrrr
Saeed [looking sick]: Abdul...I don't have a scabbard.
Abdul: [turning to look]: You do now!
The core logic wasn't too bad (except that I was very green at the time), but the interop between C++ and Obj C parts was truly painful and part of why I became a web dev for years after.
I've noticed he doesn't know everything, but he knows a lot.
There are exceptions to statements like this.
I'd change "never" to "almost never".
For one thing, when a language feature doesn't really work out, the user community will notice and it'll disappear from most codebases. If a Java developer with 20 years of experience has never worked with java webstart - is their mastery incomplete?
And even for features that aren't deprecated, almost no jobs will demand every feature a language offers. A veteran Java developer with 20+ years working on high-performance backend server code might not know much about JavaCard, or packaging their code for use on Windows, or the state of the art in making GUIs, or the latest kitchen-sink enterprise framework - is their knowledge incomplete?
Of course, some would say if your definition of "knowing a language" is so demanding that nobody meets it, some might say that's an unrealistic bar....
But this is true of almost any popular language! By the metric people are applying to C++ here, there is no one on earth who "knows Java", which is patently ridiculous.
A better metric would be "Can write code in that language for some domain".
Can you though? C++ chooses to sidestep Rice's Theorem with IFNDR (Ill-formed No Diagnostic Required). IFNDR is sprinkled on lots of the ISO Document and what it basically does is, everywhere the language needs semantic constraints for soundness Rice's Theorem would otherwise make it theoretically impossible to write a C++ compiler so they just say well, if you break this semantic constraint you haven't written a C++ program. The compiler won't know, and neither will you, but it's not our fault if your program doesn't work, it was actually never a C++ program anyway.
This is a great rhetorical device - if the goal was to win a debate championship this sort of sidestep is very clever. But obviously it's going to produce a vast amount of nonsense, it's terrible engineering practice, and yet for decades people acted like this was OK.
Also, this graph is from 2010, so it's missing some lambda magic, auto vomit, and static object initialization got easier since.
In a personal conversation, that person told me that he estimated that he knew about half of the language, and that average career length wasn't enough to learn all of it.
This was way before C++11.
I've been working primarily in C++ since the days when there weren't even C++ compilers (you instead ran the C++ code through a program that turned it into C that you compiled with a C compiler). By any reasonable measure, I am proficient in the language -- but I think I'm actually proficient in about half of the language, same as your coworker.
This is also why I've moved away from C++ in the last few years. It's too unwieldy for me to use as a default language anymore. Now, my default language has become C++-as-a-better-C rather than full-blown C++.
GNU g++, MSVC C/C++?
ISO C++98, C++03, C++11, C++14, C++17, C++20, draft C++23?
I like the OP's curve, but realistically, there needs to be a set of curves next to each other, because every 5 years, C++ changes a lot to the extent that you can write "idiomatic" code that looks very different from half a decade before.
I've been using C++ since the 1990s, but mostly, overall whenever I used C++, I stuck to a subset of C++11 or C++17. Compiler errors always have been a pain, which is still the case now, and no two compilers compile the same language (unlike Java, whatever complaints you might have against it).
I normally expect at least C++11 when interviewing, but let the candidate use whatever standard they are more familiar with (and even non-standard features, especially around threading).
When new people asked him if he knew C++ his standard answer was "I know enough to know I don't know C++".
How do you even physically do that?
Generous estimate:
1M LOC
18hr days * 3 = 54hrs
1,000,000 / 54 ~ 18,500 LOC/hr
There must have been a lot of help from automation here or you had an enormous amount of boilerplate code, because otherwise I don't understand how this is even possible.Then replace some large modules with existing 3rd party libraries, and the whole feat sounds a lot more believable.
This is the result of both being able to cleanup & simplify, as well as completely ignoring edge cases and regressions :)
- If you map out the entire system, and understand how all the pieces fit together, you can: make something simpler that fulfills reqs/does the same exact thing; use template metaprogramming to generate the source code for you, instead of writing it by hand
The only issue is very few people will have the skills or the patience to sit down and try to understand metaprogramming. So you won't be able to take advantage of it in most business use-cases (i.e. won't easily be able to find another cog to work on it), despite how powerful it is.
It's like why more people don't work with K (or functional langs, etc.): it's not a simple procedural or OO language, so it's harder to learn -- and harder to get started with.
It is far less impressive than it sounds, because it relies on having an unimaginably bad starting point.
I guarantee you that the starting point for this story was a pile of copy-pasted classes, each of which had some minor tweak, and that the program exposed some combinatorially large number of similar flows. When a bug was fixed, it would need to be manually applied to dozens of classes, and this did not happen, so each of the copy-pasted classes diverged and replicated functionality.
The output of the weekend was almost certainly a simple set of software layers, each with a clean mathematical abstraction, and the composition of the layers expressed all possible flows from the legacy system.
The best example of this I've heard of was with inkjet printer drivers from HP. They used to fork their entire driver stack, including font rendering and dithering, for each printer they released. They produced dozens of models per year. Then they assigned 5-10 full time engineers to maintain each fork of the driver.
After the open source people had already done it with reverse engineered stacks, someone at HP wrote a unified driver framework where the only model-specific stuff was parameterized inputs to the ditherer (DPI, etc) or the actual wire protocol over USB to send the list of dots to put on the paper.
They ended up replacing something like 10,000 engineers with a dozen people or so, and printout quality increased dramatically (though I doubt it was as good as the open source stacks).
These days I don't write much C++ code (regressed to largely C), and when someone asks me how proficient I place myself at a 4 out of 10, and then explain how the spec has changed faster than I think most people can actually absorb it unless its their full time job to sit on the standards committee. So I don't believe anyone who gives a themselves a score over 6 unless their job actually required a deep level of standards understanding (ex: compiler developers).
OTOH, all that doesn't mean my actual C++ style has changed much. I still use C++ as a C with objects, only now some of the restrictions of the past have reasonable workarounds. So the idea that only beginners treat it as a C with objects language is a misleading statement. Sure I can create all kinds of fancy language constructs, but I only use things like template meta programming in toy projects or various other features, but the results are frequently setup as "C" language extensions (aka here is a matrix class where the matrix T can be a bignum/etc) which happen to look more like a C compiler with some extra features for manipulating matrix's.
A lot of the problems (ex threading is hard) come from the fact that its far to easy to dig a comprehension hole that even the initial programmer cannot get themselves out of. Hence projects like firefox/thunderbird from ~15 years ago where the C++ code was hacked together in a style that needed to be cleaned up but never was, leading to piles of hidden bugs, and problems where newer/stricter compilers would simply refuse to compile the code due to undefined behavior on ever 10th line.
I generally factor in a ~5 year adoption period for newer standards as not only compiler adoption completes, but as distributions pick up newer compiler versions and make them the default.
So right now, I'd consider c++17 the expected standard for people to generally be comfortable and competent with.
One tip: template metaprogramming can consume your life. Avoid it, but use templates sparingly; they do simplify code, especially for vector types.
The key with C++ zen is “all things in balance.” You can go too far with basically every aspect of the language. And it’s important to go too far, so that you know why not to.
I'm teaching a HPC (threading/openmp/mpi) class and that's exactly what we do. We switched from regular C to C++ for classes and some standard library data structures and that's that. It makes our lifes easier and stuff is still "easy" enough to understand and work with.
I've once had to work with a cryptography codebase using excessive templating. It was an absolute nightmare to deal with and the only person I know of able to understand the codebase was the original author.
I like to use templates to replace #define style programming. As it makes it easier to debug what is going on and get the compiler to work for you instead of in the background and hoping it spits out the right thing to feed to the next stage in the compiler pipeline.
Many languages have these sort of 'yeah you can do that but you probably shouldnt' things. C++'s version of that is templates (for a long time it was giant trees of classes). You get sucked into how cool it is then realize you have made a horrible mistake and made a giant mess that you can barely comprehend much less debug.
Readability and maintainability are the key features of good source-code. Therefore - I back off if someone tries to make the code itself “art”. The result shall be reliable craftsmanship. A usual, apply reasonable exceptions ;)
If you mean member functions, virtual functions and inheritance, I beg to differ.
• Cast a (pointer to a float) to a (pointer to a uint32_t). No; even if you make sure the size of a float on your target platform is 32 bits, this is undefined behavior.
• Make a union of a float and uint32_t. No; this works in C (since C99...?), but in C++ "it is undefined behavior to read from the member of the union that wasn't most recently written." [1]
• Use reinterpret_cast<uint32_t>. No; this violates the type aliasing rules, and the behavior is undefined. [2]
• Use reinterpret_cast<unsigned char> or reinterpret_cast<std::byte> and then reassemble these into a uint32_t. Yes! this works, although slightly laborious.
• Use std::memcpy. Yes! This is perhaps the "right" answer. The compiler should recognize the idiom and elide any actual copy.
I'm not even confident that I have that correct. It's an enormous language to fit into one's head; the language specification runs about 500 pages long and the standard library another 1500. [3]
[1] https://en.cppreference.com/w/cpp/language/union [2] https://en.cppreference.com/w/cpp/language/reinterpret_cast [3] https://github.com/cplusplus/draft/releases/tag/n4917
*This is a joke, but only barely so.
Which is something that hardly makes any sense and most professional will never need in their entire career.
edit: are you also expressing disagreement with the claim that few C++ programs are correct (and the implied claim that this is because many people's first-guess approaches are actually incorrect), or just saying that you think this is a bad example of the language being complex or misleading?
That requires a cast from float* to void*. Reading the floating point number as an integer is not necessary.
Casting any object pointer to (and from) void* or char* is guaranteed to work, while float to integer incurs in the undefined behaviour curse.
for (int i=0; i<4; i++)
buf[i] = ((char*)&my_float)[i];
is not undefined behavior? But that for (int i=0; i<4; i++)
buf[i] = ((char*)(int32_t*)&my_float)[i];
is undefined?On the other side, this would incur UB:
int32_t my_int = *((int32_t*)&my_float);There is no sane reason to want to access a float as an integer.
Actually, I wonder if you do ;-)
You insisted you want char *, by which I understood you meant bytes. Rust can do that too, but now you need to care about byte order. Seeing another answer in this sub-thread I realise you actually meant you wanted a string which is doubly hilarious in a C++ thread. The char * is a pointer to a byte, C++ has actual strings (and, these days, even a passable fat pointer style string reference called std::string_view) and they're different.
it is technically UB, but it works as a documented extension on pretty much every compiler.
> If the member used to access the contents of a union is not the same as the member last used to store a value, the object representation of the value that was stored is reinterpreted as an object representation of the new type (this is known as type punning). [...] Before C99 TC3 (DR 283) this behaviour was undefined, but commonly implemented this way.
(Of course you had it right, and HN ate your formatting, but it is funnier this way)
I think most use cases for type punning fall in 2 categories: conversions between types with same size in memory, for writing or reading as a new type(ex. read an f32 as an u32) or accessing only a part of the data, like the first or the last 2 bytes in a u32.
Ideally, there would be a way to specify that a union is used for type punning and what conversion types are allowed (using something similar to concepts or constraints). That would probably solve most use cases and also allow the compiler to easily detect it.
Now, 13 years later, if someone knows the all the language itself, libc++, common idioms, best practices and template meta-programming intricacies, I think it's safe to say they are more of a devoted learner/teacher than a programmer, as retaining and keeping up with all that knowledge won't leave much time for actual programming.
Maybe at least 10+ years of continuous C++ use would be a better measure of actual C++ skills?
Doesn't mean it is an easy language, far from it.
Still, the people jumping ship to other younger languages and then writing about it remind me a bit about someone trying to justify switching their ageing partner with a younger one. Perhaps understandable, but after some time, the problem may turn out to be elsewhere.
We'll just have to see how sexy Rust and the other current alternatives will be when they get to C++'s age, if they still use programming languages by then.
I expect Rust to grow to be about as complex as C++, except for the most part memory safe. I still think it would be a big win overall but I don't know if it will significantly displace it though.
There's no technical reason why C++ could not be made memory safe if needed, by piling on complexity, like compiler flags and checked smart pointers or something like that, but I don't know if it's worth it.
C++11 was such a major change to the language that not only was there a lot new to learn, but a lot of new best practices needed to be developed, and a lot of the common sense on those wasn't practical because of the need to interface with existing code and libraries. I feel like reasonable API design and coding style still hasn't stabilized post-C++11.
Since then I've continued to use the language daily but have given up hope of ever getting back to that relative level of knowledge. I just try to learn little bits here and there whenever it's relevant to something I'm working on.
I think the difference is a lot of people were ignoring these trends in their c++ use, and were slightly blindsided when the standard appeared to endorse them.
Also, further back in history, the ABIs for a lot of C++ features were subject to change. If you used g++ on Linux in the 90s and 2000s you've been bit by this. I'm not sure if this still happens in the modern era with the standards still iterating a lot; would not surprise me if it still does. This is another reason to avoid interfaces with a high risk of breaking ABI, which C++ features can be.
Maybe the additions could have been managed better, but I don't think there's an easy answer as to how. Hopefully, this is something that can be improved. We'll see.
The reality is, in my area, Java enterprise development pays a lot more. I'm sure this is the case in plenty of other areas as well. Surprising but true.
In an interview setting, keep answers contextual and tight. In my previous professional setting, we would solve the problem like this : <however>. Try to solve problems using only the subset you know.
if you're pushed into a corner and they really want to overload [] or whatever, be clear that because, c++ is a large and sprawling language, for production code you'll need to check the spec, or consult with a teammate. With that understanding in place, you can take a stab at it.
If you get dinged for that, you probably don't want to work there anyway.
I find it so frustrating how hard this is to sell in an interview. I understand how important it is to avoid bad hires, but I'm a self-taught web developer so I just flat out don't know a lot of CS "basics". I've been a professional SWE for 5 years, have made all of my teams very happy, have accomplished some very good work, and have dug into the docs enough to get the most out of the many tools/libraries I've had to use.
But, sometimes there's a coding challenge on a topic I've just never seen before, and I'm dropped. As unrealistic as it is, I wish interviews had options for demonstrating my ability to learn a new tool quickly and make use of it. I'd spend a work day taking on a mock ticket for some new security procedure I've never touched before if it showed them that I can actually get the job done.
I agree that asking details related to syntax are not good questions. But copying objects is a very natural thing to do in most languages, and if you don't have some idea of the implications, that's a red flag.
Also: Some understanding on default copy constructors. I think it's OK not to know whether a default one is created for you or not, but just knowing that it might be is worthwhile to probe in an interview.
Of course, these concepts are due to a poor language design, but what can you do? If your team uses C++, you need to deal with the poor design, and need people who understand the poor design.
certainly, a bad interviewer can ask bad questions (for any language), but the copy constuctor (and call by value or call by reference) is one of the basic features of c++.
Which are...?
I'm guessing, depending on the niche you work in, your basics are very different from many other niche's C++ basics. If you're working in FPGA development you'll have very different basics then a fintech. Likewise, game development is very different from backend web dev. C++ at Facebook is probably very different from C++ at Microsoft. Microsoft Kernel development C++ is probably very different from Microsoft Windows 11 adware C++.
I'm glad that interviewers exist that think they can pwn the interviewee by quizzing them on the "extreme basics", because it's an immediate red flag to me that the interviewer is acting with extreme hubris to claim that such a thing exists at all. I go back to this all the time, but when the guy who has literally been writing entire books on the esoteric features of C++ for 20 years says he doesn't trust himself to evaluate potential errata[0], I highly doubt any single person is capable of understanding the voluminous pitfalls and complexities of this large, bolted, amalgamation of a language.
[0]: https://scottmeyers.blogspot.com/2018/09/the-errata-evaluati...
I guess they're different for different interviewers.
The one I would use is something about undefined behavior. I mean, the fact that it exists and consequences. For example: "this program works, but if I add this line of code at the very end, the program crashes. Can be I sure that it crashed because of that line or some incorrect inputs to that line?"
In (almost) all other languages the answer is "Yes". Not in C++ or C. You may have a faulty program in the first place that just happen to not crash.
All other quirks and syntax can be picked up when needed. You can play around and investigate. But undefined behavior requires one to think and debug in a very different mindset. One cannot assume that a program that does not crash and gives a correct answer will do that if extended.
I've taught to freshmen students who have personally encountered dozens of different false positives and false negatives not only with sanitizers, but with compiler warnings as well. Nothing extraordinary, just `-Wall -Wextra -Werror` with the latest available GCC/Clang on the latest available Ubuntu LTS.
Some examples (some library bugs are also included):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98677
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105729
https://github.com/llvm/llvm-project/issues/59432
https://github.com/boostorg/dll/issues/30
https://github.com/boostorg/asio/commit/71964b22c7fade69cc4c...
https://github.com/chriskohlhoff/asio/issues/997
I've also seen fun examples of a program working with all sanitizers in 14 modes across 3 OSes (GCC and Clang on Ubuntu, Apple Clang on macOS, Visual Studio on Windows), and _only_ failing with Visual Studio Release mode. It was an array overflow. Just was not caught by sanitizers.
Mind you: no weird C++ magic, just standard coding exercises.
What does change is the STL. Asking someone what a constructor is, or templates, or auto, or ConstExpr, ConstInit, ConstEval and the differences. It's the exact same code on any format or machine. Asking someone what a "Unique_ptr" or "Ranges" or whatever is a bit in the bullshit realm of an interview and should be shamed. But C++ is vastly seperated from the STL. And odds are in an interview, you can ask someone about their specific domain of c++ they use in most cases, since usually a win32 shop is going to interview win32 people.
What is a smart pointer? Or if I'm sadistic, whats the difference between unique_ptr and shared_ptr? To me, smart pointers are one of the tells that you are actually writing C++, and not just C with classes.
That said, testing syntax is generally awful and I only use to gauge someone's familiarity with the language (same with Go, I'll say what is a goroutine, but Go is easy enough to learn that it wouldn't factor into my decision unless the candidate was brazenly lying about past experience).
> To me, smart pointers are one of the tells that you are actually writing C++, and not just C with classes.
To me, shared_ptr is one of the tells that you should be writing Go or something like that, and not just C++ with reference counting.
It's moreso I've had so many interviews crash on this question that I've started to feel bad for asking it (and starting to assume that, no they don't know C++).
Most of these jobs we didn't even use C++, it was just identifying C++ engineers was usually a very strong signal, especially because we were early adopters into Rust.
It's surprisingly easy to fool people with just words. I think this is why we have so many incompetent people working in tech. Most people don't know how to qualify people.
What isn't esoteric? Shared pointers, move semantics, atomics, inline assembler, CRTP...
If you quiz someone on your particular known C++ language details you can far too easily think everyone is pretending.
I do understand why Haskell is a niche language.
I do understand why Scala has fallen out of fashion.
C++ is more complex than any IT-related technology I ever saw. It was destined to fall. But it did not.
Every language which attempted to compete with C++ did so with automatic memory management or other features which were bad for performance. If the goal is to kill C++, they made the wrong tradeoffs and introduced anti-features from a C++ pov. Only recently have we gotten languages which actually compete with C++ on this level like Rust, Zig, Odin, etc.
It's also because it extend C, and C is the linga-franca of programming.
Got them reversed?
The people that think Rust is 'the next C++' are delusional. The next C++ will be backward compatible with C++.
It also remains to be seen if it'll work. A lot of people don't trust Google and languages take a long time to build.
You are bound to find _something_ that works for your usecase in there.
This is also why it's fast. You are not required to use any particular thing.
C/C++ will always be around no matter how hard replacements are thrown at it. C++ is the Grand Canyon and attempts to dethrone it from what it does best are mere rainstorms adding to a river at the bottom of the canyon, maybe one day but that day is not close.
C/C++ work well together and this made them win along with the power and timing of coming about in the application age.
No matter how many years they worked, how many projects they have shipped, how much code they share on GitHub, disregard everything and require multiple rounds of rectal examinations every time they apply for a job. They could have written millions of lines of code, it doesn't matter coze it's not the latest fad and anything before last week's paradigm was just monkeys hanging out from the trees, it was clearly impossible to write any business logic before last's week invention of <insert latest craze here>.
Find some obscure crap you freshly read about that they don't know or don't remember since using it once 20 years ago and apply the very correct and fair logical inference "IF THEY DON'T KNOW EVERYTHING THEN CLEARLY THEY KNOW NOTHING".
Something along this: "So... you call yourself an English speaker? Native, ehh? Read plenty of books, wrote Medium articles? We'll see about that. OK, use 'Floccinaucinihilipilification' in a sentence that makes sense! Don't know? What a surprise! OK, one last chance, try not to omnishamble again. What's the velleity of the quincunx tintinnabulation? ... Just as I thought, you're a fraud and a sham and clearly don't speak English".
Programming languages known:
C/C++, HTML
This is usually a good sign that this person can probably complete these exercises:Write a program which display a number between 10 to 100 randomly.
Write a program which accept a letter and display it in uppercase letter.
To be fair, I also write some Lua, Javascript, Python, and I have sideline love affairs with Rust, Zig, Scheme, Common Lisp and others. But I've never had to write serious software in any of these, so applying for jobs where that's the main language would at least require me to honestly say "it'll take a little while before I reach maximum productivity".
That task is a lot harder than it sounds, given that casing is locale-specific. In a Turkish locale for example, I would expect a lowercase "i" to be converted to U+0130 "İ" instead of "I" like in en-US.
And then there's the whole ambiguity around the word "letter". Is a letter a single code point, or a grapheme cluster? What if someone passes in an emoji? With multiple zero-width joiners? Better make sure your dependencies are up to date so you know what's a single letter and what's too many...
Here is an example MIT course from 2011, it introduces C-style arrays and C-style strings in lecture 4, pointers in lecture 5, and classes in lecture 6: https://ocw.mit.edu/courses/6-096-introduction-to-c-january-... (although memory management is postponed)
Another MIT course from 2014 explicitly starts with C, but it has "C and C++" in its name: https://ocw.mit.edu/courses/6-s096-effective-programming-in-...
Surviving that (and the ample choice of exquisitely carved tribal foot guns on either OS) was an interesting experience.
It's going to transition to "python with static types", "rust without a borrow checker", "java with manual memory management", etc.
I don't think that as time progresses the newcomer pipeline is going to be largely represented by people coming from C.
The curve described is what it's like to pick up any language after being proficient with another though -- nothing specific to c++. c++ is just larger and more sprawling with more footguns and other things to make you suffer.
Find similarity, be comfortable enough to be productive, gain experience and realize mistakes, get frustrated, either walk away or accept the language and ecosystem as it is and learn how to work within it.
It’s still useful, just not super critical anymore. You won’t feel like you’re missing out if you avoid it.
to be clear I'm not a hw eng myself so I don't have a deep understanding of hw eng, but I have a friend who's studying EE and from what he asks/tells me sometimes, there's a non-trivial amount of coding involved depending on what it is you're working on. So mabye it's because hw engineers may have experience writing lots of code which is non-trivial, but nowhere close to what a sw eng does still, hence giving a wrong impression.
I see the same with a certain subset of finance people who learn Python, and start thinking coding is easy. Yeah, fair you can whip some simple Jupyter notebook using Pandas to analyze time-series. Now build out a distributed, fault-tolerant ETL (CRUD++) system that follows all business rules, is maintainable/readable, and can scale to atleast 100 "servers."
Perhaps not the most apt comparison -- but the fundamentals in every field are easy to learn; but working at the edge is something you have no experience in until you do.
Ironic post from the person who thinks Reddit would be trivial to recreate. Your whole account reads like a parody.
It's probably similar in a lot of areas, you stand on the tip of an iceberg and you think you've seen the whole thing.
I see something similar in trading code. You get someone who knows a lot about how markets work, and they figure out that you can hack a few things together in python. Now they're a software engineer.
I think a massive part of it is that Software Engineering is better than hardware engineering. The software engineers are great! They have all these tools and documentation and they're free and open source! So there's no barrier to entry for a hardware engineer to pick up C++. But if a software engineer wants to pick up like Verilog for example... Well firstly, you're going to need expensive hardware, secondly the tooling is all closed source propriety and costs thousands to license. Oh, and there's no CI, the debuggers are tcl based tools from the 90s. etc. etc.
A hardware engineer can pick up software tools and solve the tiny part of the orchestration that needs to be done in software easily, but there's no equivalent where a software engineer would pick up hardware.
Edit: changed "incompetent" to "inexperienced" as it better reflect my opinion.
The principle of scope, and scope-bound (and scope-bound objects) really took of recently, and i'm pretty sure a better name than RAII exists now (especially since RAII doesn't mention deletion, and resource deletion is litterally the point of RAII).
He might know about SFINAE, i didnt (but i never got into C++ metaprogramming, and he did).
"recently"? - you are joking. i suspect that neither you nor your brother know much at all about c++. RAII and scope are both core ideas in c++ and always have been.
I would say that's debatable. RAII definitely dates back to the earliest days of C++, but you don't have to know it in order to use the language. Even today there are many professional C++ devs who've never really learned RAII because they write C with classes style code. I first started learning C++ about 20 years ago and IIRC at the time usage of RAII was still in the minority but there was real momentum towards it being considered the "right" way to do C++.
I'm not claiming that it's good C++ code (or good code by any measure) but I imagine those "C with classes" devs would do something like:
my_string* s = new my_string();
s->initialize("hello world");
// ...
s->destroy();
delete s;Also RAII is not (just) about scope, but bout tying, recursively, the lifetime of a resource to another one. You might even have manual destructor calls at the bottom of the tree, the rest would still be RAII. If it was just about scope, higher order functions would be sufficient.
Your power supply is specified to accept 90v-260v 50-60Hz and deliver 12v at 1 to 20 watts, in ambient temperatures between -5°C and 55°C? You can test over the entire input range, your expert knowledge assuring you that if it's tested at 20°C and 22°C there's no need to test at 21°C.
On the other hand, if your software is specified to correctly validate a SAML assertion? It's simply not possible to enumerate all the states the system might encounter.
(This isn't to say software isn't more complex than hardware: just that I think software engineers have a tendency to romanticize the level of competence and confidence other engineering disciplines have in their designs)
I agree that the point where the power supply dissipates the most power, or the point where it starts making an audible whine, might be in the middle of its operating range rather than at its limits. You would certainly want an experienced engineer who can say what density of parameter sweep is appropriate.
This is what I was trying to say when I said that when testing a system designed to operate between -5°C and 55°C, expert knowledge might assure you there was no need to test at 21°C if it had been tested at 20°C and 22°C successfully.
One way we assess stability is by doing frequency sweeps. What allows us to infer stability from that test is the assumption that the system is linear time invariant (LTI). We assume it's LTI because we tried to design it to mostly act that way, even though it's really not.
For an LTI system, a frequency sweep and a step response are completely equivalent and interchangeable, it doesn't matter which one you use. But what actually happens is the step response test reveals different information. This can only happen if the system is not LTI. Therefore neither test is conclusive about stability, though they're still informative, which is why we do them. 10x density would be no less inclusive.
Another problem is that some stability issues have very low observability. The blip or offset they cause in testing is indistinguishable from normal switching noise and measurement imperfections. They only really reveal themselves when they become a problem in the field. 10x density wouldn't find the issue because it's caused by some other combination.
Explaining and fixing those issues is tough, and anticipating them requires an arsenal of models developed from someone's hard earned experience.
I don't mean to diminish the density issue. That's still a real thing, but it's kind of an orthogonal problem. The formal term is optimal design of experiments, and in simulation we use search methods like Monte Carlo because it's not feasible to enumerate the design space even on a computer, much less in a real test.
Testing doesn't enumerate the physical design space. It only enumerates a model. Only very simple theoretical models can be enumerated in practice. We have to design with much more sophisticated and accurate models that can't be enumerated, and we have to settle for knowing that even those models are inadequate to describe everything we need to account for. We do our best to design in a way that makes the simple, testable models valid and informative, but it's impossible to completely succeed, so we only ever test "enough" (to make money).
In my projects, where we partly used DSPs and software-defined radio, I found that the hardware guys could be amazing at writing neat modules of DSP assembly, with carefully benchmarked time and space usage. I felt that they thought "hey, software is easy, it's just wiring a bunch of filters together!" But for anything requiring more sophisticated architecture (like interpreting an EPG embedded in the data stream) they wrote spaghetti code.
Often their stuff would be nice and terse, so it could look good at first glance if you didn't really understand software. Some parts would be efficient but buggy; other parts would be correct but with terrible scaling or arbitrary size limits.
Similarly, I'm sure if I tried to get involved in hardware, and confidently thought "this is easy, it's just wiring a bunch of functions together!", I might get some of the small stuff right, but the actual higher-level hardware architecture would be equally terrible.
If there is one thing I would consider the hallmark of a programmer this is it.
They say it as it is the correct answer in an interview, maybe they believe it, maybe they dont - they however are saying the things that they need to say to be employable.
It literally has far too many ways to skin a cat, from light grooming to full on mecha brain transplant.
That being said, I concur that C++ is the language where "we need some rules" is the most prominent. C++ has awesome features, but the number of people on the planet who know all of them is way too low to rely on them (you probably can't hire any of them anyway). But a team of 10 peoples is likely to know a lot of them together, so you need to work with the intersection if you want your code to be maintainable
The Last Thing D Needs - Scott Meyers (2014)
https://www.youtube.com/watch?v=KAWA1DuvCnQ
The C++ type system really is quite... complicated.
I've worked at places where people knew the standard by heart. If ever doubt some people actually 'know C++', visit the #c++ IRC channel on Libera.
It should be a science. It should be closer to core math. And yet it often feels closer to performance arts w.r.t. the individual's level.
But C++ have so many backward compatibility hacks and old code, it is impossible to "eliminate" the complexities.
Herb Sutter's https://github.com/hsutter/cppfront could be a good strategy to clean it up.
Ok, yes, I get that he's got a larger point under that clickbait-ey slug but ehhh.