5 ms·
I used to work with C++ almost exclusively, but accepted to use more interactive languages for most of my work mostly for faster iteration. C++ is definitely no
by bsdubernerd 6y ago
I used to work with C++ almost exclusively, but accepted to use more interactive languages for most of my work mostly for faster iteration. C++ is definitely not my main choice anymore, but still use it daily.
C++ has pretty much unmatched tooling due to the massive ecosystem. I have my own long list of gripes against it's syntax and historical baggage, however it's a language that doesn't really impose a style/idiom like several other modern/newer languages do, making it vastly more applicable from anything from embedded to large-scale programs without restrictions. Modern C++ has smoothed a lot of the rough edges in terms of productivity, but it's still an overly complex language that cannot shed any weight due to backward compatibility, and it's a shame.
Contrarily to many other guys tough, I'd take a dash of C++ compared to "simple" C/C99 any day, especially in embedded. C++ can be vastly simpler and more readable, while retaining 100% control over memory and layout. Most of the memory/threading issues essentially disappear with very little fanfare, but few people talk about that.
I don't want to detract against static checking though! But I feel like newer languages such as Rust are still too young and idealistic, and haven't been beaten by implementation requirements or a system's programming language yet where your silly requirement is somebody else's essential feature. This is how it gets ugly, and this is where C++ has probably something to say.
I still like modern languages though. I like Rust, but won't be able to use it effectively until they get rid of static compilation. I wish I had D's metaprogramming over C++ templates any day, but the GC is a again non-starter. Nim has no static checking, but it should deserve much more consideration than it currently has: it's much more pragmatic than Rust IMHO, and it's also much easier to integrate into existing programs will less hassle.
- steveklabnik 6y agoWhat is "static compilation"?
- deleted 6y ago[deleted]
- abdulhaq 6y agoIt's not just-in-time compilation. Maybe he wants a kind of REPL for Rust - I guess?
- pdimitar 6y agoFair and accurate points. I admit Rust needs to sort some kinks out still but it builds up on the experience of C++ and I believe it's already heading in a very productive direction. I love what they're doing with their async stack, being just one example. I can't deny compiler and linker speed in general are better in C++ land but Rust is gradually catching up (too slow for my taste still but sigh). That's a very strong point against Rust to this day. You might be right that compromises for running in embedded environments might load Rust with the same ugly historical baggage as C++. That's very possible and I can only hope it won't happen, but you do still have an excellent point about the genesis of these problems. D and Nim I admittedly didn't evaluate very fairly -- gave them half an afternoon each. They were quite nice in fact, but I found the small ecosystem off-putting, especially in a situation when I want to play with an idea that might require libraries for 5+ well-established technologies. So yeah, I wasn't very fair to them but didn't want to dedicate much time for prototyping ideas regardless.
- tijsvd 6y agoI worked mostly in C++ for over 15 years. I was totally proficient in it, and very productive, especially after c++11. Often I would reach for C++ even in favor of Python for small throw-away tools, in the knowledge that it wouldn't bail out on a typo in the final print statement after 10 minutes of analysis. I have now worked with Rust for a year, and I don't see myself ever going back to C++. The statement in the article that "only the final iteration would be unsafe if one would forget to check the length" made me cringe uncomfortably. I might have written similar code as the author, but it now looks clumsy and overly complicated.
- jnxx 6y ago> C++ can be vastly simpler and more readable, while retaining 100% control over memory and layout. But unlike assembly, you don't have control over CPU flag registers and special instructions. Can you explain why and when, exactly, 100% control over memory is needed? Outside of OS kernels, high-frequency trading engines, and real-time control systems? If using assembly is too costly, why is using C++ economical? And, do you really have control what happens at the machine level? Second and third level caches, hyperthreading, multicore, out-of-order execution, CPU affinity, NUMA, TLB, virtual memory, all that stuff, there is nothing in C++ which controls that. And I would even argue that this in most cases is a good thing, because unless you are writing an OS kernel, it is none of your programs business - what it should focus on is the logical flow of the computation. And this is what modern optimizing compilers do: They transform expressions into machine code which has an equivalent observable effect, and executes that what the programs specifies as fast and efficient as possible. Fi you write: int a = 0; for (int i=0; i < 100; i++) a += i; printf("a = %i\n", a); you could be tempted to believe that the CPU executes increments on a 32-bit or 64-bit register. This is not what happens on a modern optimizing compiler. Look at that link (which uses -O3): https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,j:1,lang:___c,selection:(endColumn:6,endLineNumber:2,positionColumn:6,positionLineNumber:2,selectionStartColumn:6,selectionStartLineNumber:2,startColumn:6,startLineNumber:2),source:'//+Type+your+code+here,+or+load+an+example.%0Aint+f(int+num)+%7B%0A++++int+a%3B%0A++++for+(int+i%3D0%3B+i+%3C+100%3B+i%2B%2B)%0A+++++++a+%2B%3D+i%3B%0A++++return+a%3B%0A%7D'),l:'5',n:'0',o:'C+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:cg102,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'1',trim:'1'),fontScale:14,j:1,lang:___c,libs:!(),options:'-O3',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'x86-64+gcc+10.2+(Editor+%231,+Compiler+%231)+C',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4 https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScal... - the compiler reduces it to a single move and return instruction. This is not specific to C++ compilers - a good Lisp or D or Ocaml compiler will to the same, while managing the memory for you. Now, control is, as in psychology, a double-edged sword. It allows you to take influence, but too much control is not a good thing, as the example of micro-management shows. In the case of the compiler, if you control too much, it interferes with the compiler's job to transform your expression into efficient equivalent machine code. The fine-tuned code you write today might be optimized for some of the modern hardware, but while it will probably still compile, it might be much less than optimal 15 years from now, and in the case of C++ without the compiler having any leeway to optimize it because you told it way to explicitly what to do. It also interferes with your job to produce clear, valid, and readable algorithms and code. And the numerous controls which C++ gives make for a very broad and very fuzzy interface, which in turn makes it more difficult to produce good code and hard to do that in a way which is both reliable, strictly valid, and easy to understand. The issue with non-ASCII characters in words in the original article is a good example. Here is another one: Take include <vector>; include <algorithm>; std::vector<bool> vb(100); std::fill(vb.begin(), vb.end(), false); is this valid code? The C++ reference says: https://en.cppreference.com/w/cpp/container/vector_bool https://en.cppreference.com/w/cpp/container/vector_bool "Since its representation may be optimized, std::vector<bool> does not necessarily meet all Container or SequenceContainer requirements. For example, because std::vector<bool>::iterator is implementation-defined, it may not satisfy the LegacyForwardIterator requirement. Use of algorithms such as std::search that require LegacyForwardIterators may result in either compile-time or run-time errors. " Do you think this is funny?