4 ms·
I work on UI for universal Windows apps where the choice is C#, C++, or JavaScript. Modern C++ is pretty nice if your team is ready to embrace it and leave old
by Aleman360 11y ago
I work on UI for universal Windows apps where the choice is C#, C++, or JavaScript.
Modern C++ is pretty nice if your team is ready to embrace it and leave old styles behind. I still use C# for utilities and prototypes but for production stuff, users' time is more valuable than mine.
- pcwalton 11y agoThis comment fails to address the main point yosefk was making: that C++ is not memory safe, and C# is. In fact, it completely ignores the point in presupposing that C++ is for "production stuff" and C# is for "utilities and prototypes", when the point of memory safety is to make your code not fail in production.
- Aleman360 11y agoEmbracing Modern C++ (RAII, STL, range-based for loops) helps you avoid a big chunk of memory safety problems. Contracts and some of the stuff in the new Core guidelines take it further. Everyone's needs are different obviously. The stuff I work on has tons of users and start up perf and minimal memory usage are primary requirements. Most of our bugs are nullptr access violations or straight up programming errors that C# doesn't shield you from either.
- pcwalton 11y ago> Embracing Modern C++ (RAII, STL, range-based for loops) helps you avoid a big chunk of memory safety problems. Not really. RAII still allows for dangling pointers/references. The STL is vulnerable to iterator invalidation. Ranges are likewise vulnerable. > Contracts and some of the stuff in the new Core guidelines take it further. How do contracts help memory safety? The ISO Core C++ bounds/lifetime checker does, yes, but as I mentioned in the other comment I don't know whether it is still going to be C++ in practice. > The stuff I work on has tons of users and start up perf and minimal memory usage are primary requirements. Those are valid reasons to use C++, yes. > Most of our bugs are nullptr access violations or straight up programming errors that C# doesn't shield you from either. C# doesn't make null dereference undefined behavior :)
- blub 11y ago1) Using smart pointers makes it really hard to have dangling pointers. 2) The invalidation rules are pretty well known at this point, but I concede that it's much better to have compile-time validation. A good STL impl will have iterator debugging, which catches iterator invalidation. e.g: debug mode in GCC 3) Regarding null, you're theoretically right, undefined behaviour and all. In practice[1], accessing a null pointer/reference will result in a crash both in C# and C++. When developing Java apps (C#'s big brother), the biggest sources of bugs during development were null pointer exceptions and unhandled exceptions propagating to the event loop and killing the UI thread. [1] There are strange cases such as http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html?m=1 http://blog.llvm.org/2011/05/what-every-c-programmer-should-...
- pcwalton 11y ago> Using smart pointers makes it really hard to have dangling pointers. No, it doesn't. std::vector<std::unique_ptr<int>> x; x.push_back(std::make_unique(1)); auto& y = *x[0]; x.clear(); std::cout << y; // use after free This is, of course, a toy example. For lots and lots of real examples, search Web browser engine bug trackers for UAF vulnerabilities. (They have been using smart pointers exclusively for a decade or so now.) > A good STL impl will have iterator debugging, which catches iterator invalidation. Valgrind and ASan catch UAF too and have been around for years and years. Yet we still have a ton of UAF vulnerabilities.
- blub 11y agoWith C++ one needs discipline to make up for the lack of type safety that one can get in other languages. This is of course not so great, because it relies on the programmer to know various idioms/patterns. In your example, it would be a major red flag in code review to create a reference like that. Some code constructs are just asking for trouble. I think the reasons behind still having errors despite tools like Valgrind and ASan are: a) many devs don't know about them or use them b) you need 100% coverage to remove all errors Using said engineering practices will not result in a completely big-free program, but it will have a significant impact on the quality. For something that doesn't have the nightmare security profile of a browser or various other exposed services, that can be just fine, even if not ideal.
- mwcampbell 11y agoDoesn't .NET Native address startup perf, particularly for UWP applications? I'm guessing the reason why C++ yields lower memory usage than C#/.NET is because RAII and reference counting ensure that memory is always freed as soon as it's no longer needed, whereas garbage collection only ensures that memory belonging to unused objects will be freed sometime later. Is that correct?
- pcwalton 11y agoAlso stack allocation and pervasive use of value types help C++ a lot in practice. This reduces overhead of heap metadata. There's also the overhead of .NET wrapper objects for OS resources--compare a .NET window object to an HWND, the latter of which is just a word-sized opaque ID describing a kernel managed resource. Though GC has its own advantages too--the ability to compact being the main one.
- Aleman360 11y agoHaven't seen any benchmarks but I'm guessing the baseline working set of a .Net Native UWP app is still megabytes bigger than a C++ UWP app. *edit: ~16 MB for .Net Native, ~10 MB for C++ using latest VS2015 targeting x86. Not going to matter for most apps, but for system UI that has to run on multi-user servers it does ;)