C++ Dev Ecosystem 2021
jetbrains.com
jetbrains.com
Overnight VSCode has become the one size fit all for everything.
...I feel like back when working with XCode, stuff just sort of worked.
The Embedded section has no usage listed at all for Keil uVision or STMcube. That’s quite strange to me — not that they would be some small fraction, but that they would be entirely absent.
I'm in gaming and I wish our codebase would reasonable work within VS Code but VS2019's tools just feel more "firm".
I use VS Code on smaller side projects though. It's much lighter.
Being "just an editor" was just a way to stealthily get its foot in the door. VSCode is already very much a full IDE for some languages, and the list is growing.
The only thing that bothers people is how this tech has been implemented by Microsoft in their product, with all possible dark patterns, starting with opt-out to changing telemetry controls subsequent versions to not being able to opt out at all, depending on the product.
I have experience using VS from work and other (open-source) IDEs from hobby projects.
Coming from open-source, VS Code seems pretty large, unwieldy, and corporate.
Coming from VS, VS Code is reactive, flexible, configurable, and modern.
What I want to say is that "A fresh reboot of VS" isn't just a marketing gimmick, it's something that I would think many VS users (especially those that haven't gotten used to VS's oddities for 10 years) have been clamoring for.
I mean that wrt. the state of Visual C++ - I spent months coding in unaugmented Emacs, without support of LSP[0], running build commands manually, because that was more productive than VC++ that would regularly freeze or crash for no reason. The only reason I keep it around now is because I need its build tools, and because of its debugger, which works great[1].
It's a stark difference compared to my experience with Visual C#, which I consider a solid, robust product.
--
[0] - Took me a while to block off some time and get clangd to work with the idiosyncrasies of both the codebase and my Emacs setup; now that I've done that, I'm a happy camper and need VS Code no more.
[1] - Of course, I invoke it on demand via `devenv /debugexe`, not by keeping the project open in Visual Studio. On that note - if anyone knows a good replacement for MSVC debugger, I'd love to try it. Extra points if it works with Debug Adapter Protocol - though as far as I can tell, there aren't any DAP-compatible debuggers for C++ outside of vscode-cpptools.
LSP commoditized IDEs, by disentangling IDE features from underlying programming language. To be honest, I'm very grateful for that - that's how I get to write C++ in Emacs, with clangd and lsp-mode, and enjoy most of the benefits of Visual Studio at fraction of performance price (and crashes). What were IDEs complementary to, for Microsoft? Not sure, but I'm guessing the Azure platform.
As for fire and motion - it so happens that LSP is intrinsically tied to VS Code. It may be an open protocol, but VS Code is essentially the reference implementation, so the protocol is shaped by the needs and ideas of Microsoft. Language server development gets directed by MS, while LSP clients play constant catch-up game with VS Code, leading more and more developers to switch to the latter.
I'm not sure whether to consider this a good or bad development: it's pretty clear Microsoft is doing this (and other things, like GitHub acquisition) to cast their nets over the whole practice of software development - but on the other hand, LSP is a genuine improvement for the industry, and huge at that, and with pretty much no strings attached.
VSCode definitely does those basic requirements very well, and allows me to just fire off a custom (or not) build command. No fighting VS to get clang working or whatever.
That is extremely amusing and also extremely understandable.
[1] https://clang.llvm.org/docs/MSVCCompatibility.html
[2] https://blog.llvm.org/2018/03/clang-is-now-used-to-build-chr...
[3] https://blog.mozilla.org/nfroyd/2019/04/25/an-unexpected-ben...
[4] https://docs.microsoft.com/en-us/cpp/build/clang-support-msb...
You can use both MSVC/Clang-CL..
The primary reason I find to still use MSVC is that it compiles faster.
Most of us live on .NET and C++ mixed code bases, and enjoy our IDE tooling for all levels of Windows stack.
Eclipse CDT, the long time king in embedded world, has been deliberately hidden from the default list. You have to click 'all results' to see it. Such a nasty trick!
PS: Eclipse can support all project long before LSP/Clion appeared, provided that 'CDT GCC Build Output Parser' is setup properly.
https://chromium.googlesource.com/chromium/src/+/refs/heads/... https://developer.mozilla.org.cach3.com/en-US/docs/Mozilla/D...
Please note that 16G RAM is assumed, I use 32G on my own laptop. I use Eclipse CDT for more than ten years successfully on all kinds of embedded projects.
Integration tests and fuzz testing is where it's at. Anyone can add or improve an integration test within an hour and find several bugs that real users would encounter.
Well, that might be the problem. Testing "for bugs" isn't a terribly helpful activity. Testing for behavior is much more helpful, and unit tests can definitely be applied to that aspect of the system. Of course, it requires you to properly decompose the system into subsystems (modules) with loose coupling that can be individually (or in small sets) loaded into test harnesses for testing.
I have written tens of thousands of unit tests in my career, and by far the most useful ones are the ones that point you to the exact subsystem in which a bug you've just introduced during refactoring/re-implementing lies. Bad unit tests are brittle "change detectors" and make you constantly adjust them for no real reason. I find mocks and interaction-based tests (rather than simple input/output tests) are this way. I flat-out do not use mocks for this very reason. They are intricate, involved, and take huge amounts of time to load context when they fail. Don't write such tests.
If your unit tests are garbage, it's because they were not thought out very much and commit sins.
This is why I prefer integration tests. Most of my projects interact heavily with a database. Making it an integration test unless I mock it out. Which I don't do, because in my experience, doing so tends to hide lots of bugs.
IMO integration tests are great for making sure that your system actually functions with all its parts together. Nothing but an integration test can do that. But unit tests serve a different role: reducing the scope of the system under test so that you can pinpoint exactly what part failed when it does fail. They help you iterate quickly in refactoring, and when something goes wrong in production (or a bug report from the field), they narrow the cone of uncertainty by eliminating from consideration the parts of the system that are working correctly. In my experience, this rapidly cuts down on the amount of wild goose chases one goes on and overall makes a team more efficient. Then once a bug in the wild is found, the system responsible for the failure gets new regression tests and unit tests. Sometimes, I wrote unit tests for units I am suspicious of as I am debugging, and even if those tests don't find a bug, I might keep them.
I worked for 6+ years on V8 and the parts of the system that were the least unit tested seemed to be home to far more production issues than others.
It also helps a lot to keep your unit tests running super fast. Under 1 second is ideal.
As I say, some people will still think of this as integration testing just because there’s a lot of moving parts working together. But often you’re just testing fairly pure code with no external or IO dependencies so I’m happy thinking of these as unit tests still. Where those types of dependencies exist I do still mock though.
It's fascinating, I agree with the rest of your comment wholeheartedly but am a heavy mock user. Much of the code I interact with has complex logic with well-defined and discrete interacting objects. Without mocks, the combinatorial explosion of input/output behavior means tests are extremely difficult to write, or more likely, are written incompletely, without properly enumerating the invariants expected of the interfaces under test.
I'm currently working on a complex system right that's safety-critical but also SOTA, and full of domain experts who are decisively not engineering experts (among other things, engineering expertise is part of what I bring to the table). Well-defined invariants and narrow unit tests that enforce them are a _god-send_, and I'm literally not sure we could function without them: as we're constantly refactoring the system to work in different ways, automated testing of invariants enables a whole universe of experimental changes that would otherwise carry a great risk of introducing bugs into other parts of the system. Our system is far too complex for integration tests to cover a fraction of the completeness that unit testing enables (though we also have simulation/integration tests, of course).
Case in point: I'm a hobby C++ hacker, and I read this. I'm a long time pro Python hacker and would not have opened something similar for Python! I'm like "the last thing I need to read about in my leisure time is what other people are doing with Python, that's WORK." haha.
Surprisingly 93% of Java users surveyed write unit tests though. I thought Kotlin would be similar, but for some reason JetBrains doesn't show any responses for Kotlin users.
Java percentage is unit test is so high most probably because it's an enterprise language. And the whole unit test craze started with Java and jUnit.
I'm not sure that's the main factor. Compared to C# & C++? I don't think "enterprise" has much to do with it.
Of course, I am sure many of those survey results are people that don’t write unit tests when they could and should.
I've seen 100%+ code coverage on cross-compiled bare-metal C++ embedded code. If that can be tested, then anything can be tested.
There are broad classes of software, notably high-performance data infrastructure, where unit testing manifestly doesn’t make sense. So people don’t write many unit tests even though this is mission-critical high-reliability software. Other kinds of testing is extremely thorough though.
The kinds of code units that are not unit testable are those where the correctness of the implementation behavior is almost completely contextualized by the behavior of external code units. As in, the unit test may be correct or broken based on the behavior of external code modules, not based on the inputs to the module. Software that is very schedule driven, like modern database kernels, has this property generally. Good integration testing picks this up very well. Writing a proper “unit test” under these constraints is effectively equivalent to a relatively comprehensive integration test.
And for parts of the code that can be unit tested, I tend to use exhaustive or quasi-exhaustive testing of their properties as part of release qualification, which is too expensive to be a true unit test but picks up more obscure errors than unit testing is ever likely to find and serves a similar function.
I believe in brutal and thorough testing. But unit tests specifically are mostly a waste of time for some of the common applications where C++ excels as a programming language.
I would have bet that the vast majority of C++ projects are not using the latest standard let alone the latest compilers that support it.
- Full C++17 support requires GCC 7 or Visual Studio 2019 or Clang 5.
- Limited support available in GCC 5 and Visual Studio 2017 with update pack.
Then the question is what packages are available in Debian/RedHat? especially the previous major version of the OS (Companies are always slow to upgrade and libraries in particular need to work on active OS until EOL).
RedHat 7 is stuck on GCC 4.8 so anybody working in that type of environment is stuck there. Debian looks fine. For Visual Studio it probably depends on whether you can get the license (have to convince procurement to pay?)
Aside of the tooling, you have to take time and be willing to upgrade the toolchain. I'd expect C++ to be the language with trillion of lines of barely maintained legacy code. (We can define "legacy" as any existing code :D)
If you are actually maintaining a large C++ codebase and all your workstations are required to run RedHat 7 for some reason, you download a newer version of GCC and run it on RedHat 7. RedHat 7 is not "stuck on" GCC 4.8.
(And I don't just mean that "you can get newer official compiler packages from RedHat and you just don't know it", like the other reply says: you can install a new version of GCC even if that weren't the case.)
And in case anyone's mind goes here: newer versions of GCC aren't incapable of generating binaries that run on older systems, either; a large number of my users are using CentOS 6 (yes: 6) and I use the latest bleeding edge compiler to compile my code.
(The secret--which I assure you most of the people who do extensive maintenance work knows--is you always "cross-compile" your binaries for Linux, even if you are on Linux already, so you have complete control over the deployment glibc version.)
Additionally, exactly to prevent the clever ones that still do it anyway,
Developers get their own group id and HOME is mounted as no exec.
Naturally I am speaking about typical UNIX shops were contractors get to SSH into the official development boxes.
There is no laptop to run code on, laptop is only for SSH and X Windows server, or cloud shell in modern "mainframes".
Nowadays one can make it one level up my having a CI/CD wall between the development environment and the actual stages, thus whatever one uses to develop must also be available on the stages, which contractors can only access with the help of hands from internal employees.
Tons of people. Anyone using an sdk for embedded or targetting older distros or OSs where upgrading runtimes are really under-prioritized by PLM.
The fact that you can find "tons" of these people only means C++ is very popular: by percentage they are going to be tiny.
> Anyone using an sdk for embedded...
Sure, if you are targeting some particularly unpopular microcontroller--one that isn't supported by gcc--and yet are somehow coding in C++, sure... but this category of C++ user barely exists.
> ...or targetting older distros or OSs where upgrading runtimes are really under-prioritized by PLM.
No: I am one of those people who "target older distros or OSs"! A lot of my users are currently on CentOS 6. Software I write is routinely deployed on like, macOS 10.6 (I don't currently support PowerPC so I can't go much lower, but this is mostly due to a lack of hardware on my end) and Windows XP; and yet I have never been locked away from a compiler feature (though it can sometimes get super annoying to support older systems and also use newer platform features, that is the opposite problem).
So: how do I do it? I just use a newer compiler! Newer compilers target old systems just fine. You just need an old sysroot. As mentioned: Xcode can be somewhat annoying because Apple likes to take advantage of LLVM being not-GPL sometimes to hide things for a while (like their arm64 backend), and they are really bad at basic software architecture principals (even their command line tooling often requires new operating systems), and yet even there: you can use newer workstations to compile for older systems; "worst case" (again: only when dealing with Apple) you also have to compile your own copy of libc++ so you can statically link it (as sometimes features of the compiler are tied to the standard library, and Apple incorrectly models the C++ runtime as part of the operating system instead of as part of the compiler or SDK).
And all this idea that modules will solve all compilation problems (such as they are)? No, I don't think so.
Probably not where you would look for vim & emacs users.
That one picked my attention.
All developers in a company are behind a single NAT IP. It's a pretty bad idea to deduplicate based on IP.
I'd hate to find out that my answers were ignored because another coworker also filled the survey. We probably all received the same survey email the same day.
For example, I use JetBrains CLion with IdeaVim plugin.
jetbrains used to be ahead of the competition, they are now lagging behind
> Is your current project planning to use any of these C++20 features in the next 12 months?
modules with 48%
jetbrains you better hurry up
Can you name a build system that supports them?
Unless you mean as in use them to diagnose an error in your use of generic code that you use. Then if you are using a high enough C++ you will use them - though probably without even knowing it.
auto myFunc(auto& x, auto& y){....}
They're technically using concepts, as auto function params are part of the c++20 concepts stuff.Concepts are pretty useless at the moment for error messages, but they're super easy and convenient when you need to disambiguate something like
void do_it(auto& x) { // x is a vector
void do_it(auto& x) { // x is nlohmann::json
Just stick a 'requires' in there and it works.1: https://gitlab.kitware.com/cmake/cmake/-/issues/18355
2: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/5562
I am a customer, i need module support because we want to embrace C++20 early, i look at what's available and i see Visual Studio supporting modules, the choice is easy to make
Visual Studio has module support since few months already
https://devblogs.microsoft.com/visualstudio/visual-studio-20...
I think you’re also confusing runtime code (dynamics) with reflection. Dynamics rely on reflection. AOT has issues where reflection would be used: generics, serialization, Activator, etc.