15 ms·
You know what? I'm going to take the controversial opinion that C++ is both the best tool for everywhere and my favorite language. C++ really has only one down
by Negitivefrags 11y ago
You know what? I'm going to take the controversial opinion that C++ is both the best tool for everywhere and my favorite language.
C++ really has only one downside. It's hard to learn. Almost all complaints about it really boil down to not knowing the language well enough.
But so what? Because once you know it well...
Once you know C++ really well, you understand what it means to have no compromise.
It has the best performance and the highest level abstractions in one package.
It has both amazing safeguards against programmer error and the ability to break all of them if you need to.
It has great portability while still giving you full access to all he platform specific features.
You can feel just as at home writing a web browser or a website in C++.
I could go on.
You get all this good stuff and really it only really takes a few years of seriously using the language to get that good. What is a few years in a 40 year career?
Also, don't believe the bullshit of "nobody really knows C++" that a lot of people claim. You can find dark corners of any language. The reason they are dark corners is because they don't come up in real code.
- hellofunk 11y agoI completely agree. I very much enjoy working in it, even after 2 years of exclusively Clojure development, I had no problems coming back to modern C++ with all its lovely functional tools and enjoy every moment of it.
- raverbashing 11y ago> C++ really has only one downside. It's hard to learn. Almost all complaints about it really boil down to not knowing the language well enough. Did you read the link and the examples shown (std::chrono one, for example) Yeah, in the time I go around trying to solve C++ self-inflicted tangles I can learn Go or code stuff in Python (or even Java/C#) which 99% of the cases is fast enough I used to advocate for complex stuff, but now I think differently. Solve my problem, I don't care about religious issues.
- quarktasche 11y agoI don't think the std::chrono example is fair at all. In the C++ case, you specify which clock you want. What kind of clock is DateTime.UtcNow()? Is it monotonic? What's the resolution? It's maybe in the documentation, but if the author refuses to remember simple syntax, surely he won't want to remember such details either. The author also chose an example where he abuses the default behavior in the C# case. The last line in the C++ example just vanishes if you use the default behavior in both cases.
- gpderetta 11y agoAlso std chrono is very strict with types: time points and durations can't be freely mixed, milliseconds and microseconds have different types [1] and you can't implicitly convert from a float based time to an integer based time. Does C# do the same thing? [1] the underlying type actually encodes the exponent as a non-type template parameter. Converting from ms to us correctly applies the multiplicative factor.
- chris_wot 11y agoBut with any complex interface, wouldn't it be a good idea to introduce a less complex facade that only deals with common usecases, and for complex use cases use that underlying interface?
- gpderetta 11y agoThe whole point of the complexity chrono interface is to prevent mistakes caused by accidentally mixing different units. Providing a default unsafe interface would completely defeat the point.
- masklinn 11y agoThat an interesting point of view to take in defence of C++ of all things.
- 11y ago
- autoreleasepool 11y ago> Python and Go > 99% of the cases is fast enough This claim is unsubstantiated hyperbole.
- hnbro 11y agohow dare they.
- autoreleasepool 11y agoRight, bro? That's what I'm saying. Misinformation is no bueno
- fsloth 11y ago"I can learn Go or code stuff in Python (or even Java/C#) which 99% of the cases is fast enough I used to advocate for complex stuff, but now I think differently. Solve my problem, I don't care about religious issues." This sounds like it's written in the hobbyist/lone tinkerer/ deploying to self managed server context. When discussing could anything replace C++ one is usually in the context of a massive business environment pending on millions of lines of C++ and native bindings, not figuring out how to write a handy personal tool. For handy personal tools, Python is probably much better than C++ 99% of time, but when discussing, how to replace a language in an entrenched ecological slot with a huge number of interdependencies things are really not that simple at all.
- loup-vaillant 11y ago> It has the best performance and the highest level abstractions in one package. The highest level abstractions, are you kidding me? I am currently writing a little interpreter in C++. I would have used Ocaml, but the rest of the project is in C++. Well, just try to write an abstract syntax tree in C++. In languages such as ML and Haskell, this is easy: type expression = Litteral of value | Symbol of string | Funcall of expression * expression | Conditional of expression * expression * expression | While_loop of expression * expression | Sequence of expression list And I'm pretty much done. Now in C++: -------------------------------------------------------------------------------- #ifndef __Expression_h__ #define __Expression_h__ #include <cstdint> #include <string> #include "Value.h" namespace Script { class Expression; class Expression { public: enum Tag { litteral, symbol, funcall, conditional, while_loop, sequence }; union Val { Value *litteral; std::string *symbol; // or a true symbol? std::vector<Expression> *composite; }; Expression(const Value&); Expression(const std::string&); Expression(Tag, std::vector<Expression>*); // takes ownership ~Expression(); private: Tag _tag; Val _val; }; } // namespace Script #endif // __Expression_h__ -------------------------------------------------------------------------------- Don't forget the cpp file either: -------------------------------------------------------------------------------- #include "Expression.h" #include <cstdio> using namespace Script; Expression::Expression(const Value& val) : _tag(litteral) { _val.litteral = new Value(val); } Expression::Expression(const std::string& sym) : _tag(symbol) { _val.symbol = new std::string(sym); } Expression::Expression(Tag tag, std::vector<Expression>* exprs) { if ((tag == funcall && exprs->size() == 2) || (tag == conditional && exprs->size() == 3) || (tag == while_loop && exprs->size() == 2) || tag == sequence) { _tag = tag; _val.composite = exprs; } else { std::fprintf(stderr, "Expression constructor: Invalid Expression\n"); exit(1); } } Expression::~Expression() { switch (_tag) { case litteral : delete _val.litteral; break; case symbol : delete _val.symbol; break; case funcall : case conditional: case while_loop : case sequence : delete _val.composite; break; default: std::fprintf(stderr, "Expression destructor: broken class invariant\n"); exit(1); } } -------------------------------------------------------------------------------- I may use smart pointers instead of doing my own RAII by hand, but that's still a hassle. Some may point out that my ugly unsafe union type is not the way to to this, I should use a class hierarchy and polymorphism. But just imagine the sheer amount of code I'd have to write. C++ is a low level language. It's high level pretense is nothing but a thin veneer that cracks under the slightest scratch. Or, someone show me how to implement an abstract syntax tree in less than 20 lines of code. I'm lenient: Haskell and ML only need 6. (Yes, I'm using Sum types, a feature that's pretty much unique to ML languages. But no, that's not cheating: providing enumeration and unions but somehow failing to combine them into sum types is a serious oversight.)
- alkonaut 11y ago> C++ really has only one downside. It's hard to learn I don't think the article lists just one downside. For example It's also undeniably hard to parse, making it harder than necessary impossible to implement efficient refactoring tools and other parser dependent tools, for example. > It has both amazing safeguards against programmer error and the ability to break all of them if you need to. C++ has two main design constraints -- it comes from C and its abstractions should cost nothing. Those two have enormous benefits and drawbacks. Performance is one thing. Other languages that don't have those design goals/constraints have different benefits and drawbacks. It's easier to make a small shell util or in perl/python than in C++. It's easier to make a formally verified system in a functional lang than in C++ and so on. "The best tool for everywhere" meaning "if you need to use the same language to solve all N problems then C++ is best of the major and widely used languages" might be true, but it's also a pretty poor metric.
- jcelerier 11y ago> For example It's also undeniably hard to parse, making it harder than necessary impossible to implement efficient refactoring tools and other parser dependent tools, for example. http://clang.llvm.org/docs/Tooling.html http://clang.llvm.org/docs/Tooling.html
- autoreleasepool 11y agoI'm curious, what languages have better support for tooling than C++?
- Sindisil 11y agoJava is an obvious example.
- autoreleasepool 11y agoI can think of several areas where Java support for tooling is unobviously superior when compared to C++. The SDK for the Arduino is good example, so is the Unreal game engine, the tooling support in Xcode for iPhone Apps, the support for static analysis via Clang, the auto formatting support via clang-format, the support in Windows eith Visual Studio, the support for autocompletion in UNIX text editors such as Vim and Emacs with the YouCompleteMe daemon and client (which leverages clang). So if Java is an example of superior tooling, it's not really an "obvious" one
- pistacchioso 11y agoHm, no, it sucks. "I can do that with ease because I've done it so many times" is really a terrible argument to explain why something is good. If you've lost a leg, walking with a crutch becomes second nature to you, but that doesn't mean that's the preferred or most efficient way of walking for the human being. Yes, you know by heart that all_of requires "foo.begin()" and "foo.end()" and the capture context "[]", but it doesn't negate the fact that many other, better languages, just know how to cycle an array without having to specify begin and end, know how to capture arguments when needed, don't require a useless (in this context) return, nor clutter a single line of code with nine differenct gibberish symbols like "(", ")", "::", ",", "[]", ";" "{", "}". Take the ultra humble javascript: foo.every(a => a % 2) When you need three times the characters to obtain the same result, and those charcters are a clusterfuck, it is not relevant if years of usage made you comfortable nonetheless with it.
- masklinn 11y ago> know how to capture arguments when needed Not to take away from your other criticisms, but in most languages how the arguments are captured has no relevance (in Javascript — and most every other managed language — the environment is always captured by reference and the GC handles lifetimes of "whatever"), whereas it is very relevant and important for C++. So I think that part of the criticism is unwarranted. Though Rust didn't go to the same lengths[0] you still have to specify whether the environment is captured by reference (the default) or by value (`move` lambdas), because that can have a large and semantic impact on the system. [0] see https://www.reddit.com/r/rust/comments/46w4g4/what_is_rusts_lambda_syntax_and_design_rationale/ https://www.reddit.com/r/rust/comments/46w4g4/what_is_rusts_... for the impressions of a C++ developers wrt what it sees as corners cut, and replies by rust devs showing these corners turned out to be mostly unnecessary in rust
- hnbro 11y agoi think having known bounds would make arrays a non-zero cost abstraction.
- autoreleasepool 11y ago> The reason they are dark corners is because they don't come up in real code. Thank you! It's amazing how much FUD is spread using examples that would never pass code review! (or even be submitted to code review unless you were playing a prank on your coworkers).
- hnbro 11y agowell, you would, you're in games. fairly substantial amount of stockholm syndrome in game programmers, imo. ;-) bjarne and others in the community have talked about the heavy cost of legacy and compatibility many times. it's okay to like the language but acknowledge that it's not as awesome as it theoretically could be. it's okay to be unhappy with the warts and weirdness -- after all, such things are what the committee needs to be mindful of when progressing the language. there's no real reason a language can't outright replace c++ without having many (most? all?) of it's idiosyncrasies. rust is a decent attempt, though the memory safety ideology seems too high friction to properly replace c++. there might be others who give it a shot someday.