4 ms·
I'm struggling with this too... I'm implementing a shell, and on the one hand I've been looking at ancient C code in bash, dash, zsh, mksh, etc. That's clearly
by chubot 10y ago
I'm struggling with this too... I'm implementing a shell, and on the one hand I've been looking at ancient C code in bash, dash, zsh, mksh, etc. That's clearly not the right way to do it, with raw strings, pointers, and globals everywhere. It's ridiculously verbose and error prone. All recursive parsers in C seem to use setlongjmp for error handling. They have weird memory management with stack allocated strings and globals too, because memory management in C is such a pain.
I tend to like "C with classes". When I started working at Google, the C++ style was a breath of fresh air over what I had seen in the game industry (this was in 2005, so C++ was in a very different state). It was very much C with classes: no exceptions, no iostreams, no operator overloading, no default copy constructors or assignment, in/out params, etc. (Lately it has been trending toward "modern C++", albeit with custom internal libraries for errors and such)
Then C++ 11 came out -- you really can't do without auto and range for loops. It looks like strongly typed enums are useful, and some STL stuff. For recursive parsers, exceptions instead of setlongjmp seems useful too (setlongjmp doesn't work with destructors AFAIK). I'm scared of R-Value refs and move semantics -- I don't know anything about those.
I guess my point is that it's 2016 and it's hard to know if there was a goldilocks moment. Google was using a restricted dialect of C++03 which I think was pretty great and built a lot of real software, but it's hard to say that C++11 didn't add anything useful.
I'm sure the Google style diverges pretty wildly from Bjarne's new effort of C++ core guidelines, which I need to look into more:
https://google.github.io/styleguide/cppguide.html https://google.github.io/styleguide/cppguide.html
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...
It seems like the LLVM codebase really knows what it's doing in terms of C++, which makes sense, but honestly it's fairly complex for what I want to do. So I think we are just stuck with all these local dialects, which makes code reuse a problem.
- ant6n 10y agoI'm not quite sure what you mean by 'goldilocks moment', but I think C++11 was it. Ever since then, the language has had a nice balance of high level abstractions at low level performance. (Theoretically it actually got faster due to move semantics)
- chubot 10y agoThe parent was asking the goldilocks question -- was there ever a point where C++ was not too complex like modern C++, e.g. this {} issue, but had enough features (contrast with C, which doesn't have enough features for many applications). I don't think there was such a moment. Apparently move constructors were a de-optimization in the case of std::vector. As far as I remember, it's related to iterator invalidation and move semantics making small-size optimization impossible (e.g. inlining small vectors into the object itself rather than having another pointer and heap allocation). I'm pretty sure it's in this video: https://www.youtube.com/watch?v=vElZc6zSIXM https://www.youtube.com/watch?v=vElZc6zSIXM Although it's debatable how big a deal this is, it's a good example of the point. People like "C with classes" because they can read the source and kind of figure out what code is generated. They can reason about locality. Although I don't consider myself an expert C++ programmer, if I can't reason about the consequences of move constructors on std::vector, which is a fundamental and relatively simple data structure, then the language is already getting into "surprising" territory. I would have never figured out that de-optimization unless I heard it in a video. On a related note, I wish that return value optimization had better syntax -- that would make move semantics unnecessary in a lot of cases. On the other hand, reasoning about the generated code is already a lost cause because assembly code is so complicated now. We now have to live in a world where we can never fully understand our tools.
- placidbox 10y agoAt what point is it mentioned in the video? AFAIK small optimization on std::vector was already invalid since .swap() needed to keep existing references/iterators valid, couldn't throw or call copy constructors/assignment. RVO being transparent would be nice, though. There's a proposal somewhere to make it guaranteed in some circumstances, but it's still fairly opaque when reading code
- chubot 10y agoSorry I don't recall offhand. It was definitely Chandler Carruth who mentioned this, and he has a handful of videos on YouTube from CppCon. They are all worth watching if you care about such things :) I don't know the details but I'm fairly sure that the issue is that move constructors in C++11 made small size optimization impossible in some cases. I think he works on the LLVM optimizer so that would be a primary source and not hearsay.