3 ms·
I feel like this is taking a very rosy-eyed view of C++. C++ has a massive amount of accidental complexity. To mention just two: the difference between () and
by dbaupp 10y ago
I feel like this is taking a very rosy-eyed view of C++.
C++ has a massive amount of accidental complexity. To mention just two: the difference between () and {} initialisation (for some types) especially in the presence of perfect forwarding, and a set of feature/their interactions that means there's a bug in the following very reasonable looking code (can you find it?):
std::unordered_map<T, U> map;
// ... initialize map ...
const U *selected = nullptr;
for (const std::pair<T, U>& p : map) {
if (condition) { selected = &p.second; }
}
// use selected
(Credit to Effective Modern C++.)
Rust may seem more complex because the compiler is noisier, but it is significantly simpler to write correctly: a computer is finding the weirdest bugs.
- soulbadguy 10y agoWhat's the bug ? (hopefully it's not just a missing break statement.
- RcouF1uZ4gsC 10y agoThe problem is that the pair in the for loop should have a const T as the first parameter. Because it does not have that, you are actually getting a temporary back and storing a pointer to a temporary in selected. The fix to avoid this is to use auto. If instead of pair, you used auto&& p: map, this would not be an issue
- blub 10y agoThat's not the point I am making. I am arguing that it's more difficult to go from idea to code in Rust because there are more programming concepts that one has to keep in mind. Additionally, the syntax is not user friendly. You are right regarding the C++ accidental complexity though. Issues like the one you highlighted tend to happen when working with pointers. They are very hard to detect during code review (I didn't see it), but I would have rejected the code at review anyway because it should be replaced by std::find. Taking raw pointers into containers is also not reasonable except for vector.
- dbaupp 10y agoI disagree that there's more programming concepts to keep in mind: the core ideas between Rust and C++ are the same (especially modern C++ with move semantics), but in C++ you literally have to keep thinking about them or your program is wrong, while Rust has the compiler checking them for you. > I would have rejected the code at review anyway because it should be replaced by std::find That specific example, sure, but there's other ways to have escaping pointers in for loops. > Taking raw pointers into containers is also not reasonable except for vector. The map types are explicitly designed to allow taking pointers, e.g. > References and pointers to either key or data stored in the container are only invalidated by erasing that element, even when the corresponding iterator is invalidated. -- http://en.cppreference.com/w/cpp/container/unordered_map http://en.cppreference.com/w/cpp/container/unordered_map
- blub 10y agoI am not so sure, I've seen examples of Rust code where I had no idea what was going on, the syntax is heavy (e.g. sigils), it's encouraging functional idioms and introduces several concepts in addition to C++ besides ownership. I don't have time to list them, anyone can find what they are. How many C or C++ programmers will understand this: (1..n + 1).fold(1, |accum, x| accum * x)? Anyway, I am just offering my opinion as someone doing mostly C++ programming. I have no problem with a language like Swift or Go, but feel that Rust is too complicated for what it offers. Taking a pointer into containers refers to &p.second. We now have a pointer to an iterator's member variable. That is unreasonable. The reasonable thing would be to use an interator to keep track of the selected item, this is what they are designed for.