[HN Gopher] Trip C++Now 2024 - think-cell
       ___________________________________________________________________
        
       Trip C++Now 2024 - think-cell
        
       Author : coffeeaddict1
       Score  : 64 points
       Date   : 2024-05-10 09:06 UTC (13 hours ago)
        
 (HTM) web link (www.think-cell.com)
 (TXT) w3m dump (www.think-cell.com)
        
       | gpderetta wrote:
       | > Google does not use std::ranges for many reasons, including
       | performance, the ability to create dangling references, and a
       | cubic stack blowup when deeply nesting some range adapters like
       | std::views::filter
       | 
       | I remember discussing this exact problem for boost range in the
       | boost mailing list almost 20 years ago. My proposal was to make
       | ranges be their own thing and generate the iterators on the fly
       | when begin/end was requested, instead of always storing them
       | internally. But I think it was not considered a big issue in
       | practice.
       | 
       | Today we have sentinel end-iterators that can be stateless, so it
       | should be possible to avoid blowout without fundamentally
       | rethinking ranges.
        
         | menaerus wrote:
         | My, admittedly, not so big experience with std::ranges is that
         | they generate an abnormal binary bloat in comparison to the
         | traditional code, so, I also tried to argue against their usage
         | in one my ex-teams who, paradoxically, wanted to achieve tight
         | execution on platforms with tight resources.
         | 
         | Another paradox was that the exceptions were disabled because
         | of reasons while at the same time std::ranges (range-v3)
         | implementation did not support this. I wonder how Google solved
         | this problem since AFAIK they also disallow exceptions.
        
         | tialaramex wrote:
         | > cubic stack blowup when deeply nesting some range adapters
         | like std::views::filter
         | 
         | I have no doubt this observation is true, but I haven't been
         | able to picture it, can somebody explain? I don't think ELI5
         | (let alone an explanation suitable for a Golden Retriever) will
         | work here, but in terms that say a C programmer would grasp.
         | What exactly gets shoved onto the stack when we're using a
         | std::views::filter ?
        
           | menaerus wrote:
           | https://schedule.cppnow.org/wp-
           | content/uploads/2024/02/Rappe...
           | 
           | Slide nr. 21 (nr. 26 in PDF).
        
             | tialaramex wrote:
             | Thanks but I saw the numbers, however to me the numbers
             | just say "It's terrible" and leave me with the same
             | question I had before, what's actually on the stack ? It's
             | not going to just be empty space left there as a joke, are
             | there... cached values? Pointers to something (what?). I
             | suspect it's supposed to be obvious but I don't get it.
        
               | menaerus wrote:
               | According to
               | https://en.cppreference.com/w/cpp/ranges/filter_view
               | return value of views::filter is either a new
               | ranges::view or some sort of range adaptor that seems to
               | be equivalent to a ranges::filter_view.
               | 
               | I can only guess that it is those return values that are
               | temporarily put on stack so that the consequent |
               | operations could be chained. My hypothesis, without
               | knowing much about this stuff, is that since the compiler
               | cannot elide them (according to the godbolt link from the
               | presentation), stack usage, as found by Google, has cubic
               | growth. I don't quite understand why since I guess it's
               | expected to grow linearly, e.g. 48 bytes at a time.
        
               | quuxplusone wrote:
               | My "Eric's Famous Pythagorean Triples" blog post is 5+
               | years old and possibly not addressing _exactly_ the same
               | issue as think-cell /Google cares about, but, you might
               | still be interested to read it: https://quuxplusone.githu
               | b.io/blog/2019/03/06/pythagorean-tr...
               | 
               | In my case, the blowup happens mainly because the Ranges
               | style tends to turn easily fungible code like `if x < y`
               | into relatively non-fungible data like the capture-list
               | of `[y]() { return x < y; }`. The former is easily
               | subjected to optimizations like the hoisting of loop
               | invariants; the latter is not. Another way to put this
               | is: The compiler is happy to mess with the layout of the
               | function stack frame up until the very last minute; and
               | to mess with the coroutine frame almost as long; but the
               | layout of a lambda (or std::bind) capture frame is set-
               | in-stone very early, by the front-end. And Ranges loves
               | lambdas.
        
         | panstromek wrote:
         | Since C++ ranges kinda look like Rust iterators, but I believe
         | Rust doesn't have this problem, can somebody explain why?
         | What's the difference? Or maybe it also has that problem?
        
           | tialaramex wrote:
           | I expect (but I'm not sure) it's because Rust iterators are a
           | deliberately thinner, less powerful idea. Suppose I give you
           | a Rust iterator A and a C++ range B.
           | 
           | You can ask A for the next() item and get back an
           | Option<Item>, this literally iterates as an inherent part of
           | getting your answer, there's no current() or previous() and
           | there's no separate finished() if you ran out of items you
           | got None instead of Some(item). A can be asked for a hint
           | about how much is left, but it's allowed to say it has no
           | useful idea: between zero and more than you can count,
           | inclusive.
           | 
           | B is expected to provide a richer, albeit unsafe, API.
           | 
           | I believe somehow this means it's only reasonable for B to
           | cache answers, as it can be asked to give the same answer
           | again and it'd be inefficient to re-calculate it, whereas
           | there is no way to ask A to repeat an answer so it makes no
           | sense for it to cache (obviously there are special purpose
           | Rust iterators which can have any feature, but the Iterator
           | trait itself doesn't need to cache).
        
           | panstromek wrote:
           | hm, so I tried this on the playground and it seems like Rust
           | iterators also scale super-linearly in debug mode (which is
           | expected, because every adaptor creates a new local that
           | contains the previous one plus something extra), but this
           | seems to go away in release mode (as everything is inlined).
           | Is the problem in C++ something different?
        
             | jcelerier wrote:
             | it's exactly the same behaviour in C++. but people are used
             | to this behaviour in Rust while in C++ they're used to
             | writing traditional for-loops which do not have such an
             | overhead at -O0 over -O3
        
           | pornel wrote:
           | Rust's iterators are single-use streams of items, and nothing
           | more.
           | 
           | A Rust iterator can be fully implemented by a closure that
           | either returns the next element or signals it's done. This
           | minimalist interface composes well, especially that it always
           | uses single ownership, so there's always only one copy of the
           | state accessed only from one place.
           | 
           | They can't describe collections. They don't remember their
           | beginning. They don't need to know their end until they reach
           | it. They can't be sorted. They don't need to support
           | splitting or iterating in reverse.
        
       | thom wrote:
       | Rappel sounds very similar to Clojure's transducers in spirit and
       | implementation.
        
       | ho_schi wrote:
       | Regarding the addition to libxx: I'm not fond of adding an
       | increasing number of specific compiler options which need to be
       | turned on for memory-safety. It should be default whenever
       | possible. What do you think?
       | 
       | I love _-faddress=sanitizer_ or _-fsanitize_. The historically
       | growing number of warnings which should be turned on are an
       | issue. For example the options -Wconversion, -Wsign-conversion
       | and -Warith-conversion shall be default with _C++XX_. And if your
       | code doesn't compile, fix it, use and older revision or turn it
       | deliberately off (saying: I'm aware, read the handbook, I take
       | the risk). Doing such changes with language revisions allows
       | people to take notice about it without surprise.
       | 
       | I want some ideas of CPP2/cppfront[1] in C++XX. Finally using
       | _#unsafe_ when needed, like Rust. C++ does evolve over decades,
       | more like other languages.
       | 
       | [1] https://github.com/hsutter/cppfront
       | 
       | BTW. Use the AddressSanitizer. Please! The toolchain improved the
       | usage and safety of the language so much. It wasn't available
       | twenty years ago but it is now.
        
         | repelsteeltje wrote:
         | I think what you're looking for are _profiles_.
         | 
         | - https://github.com/BjarneStroustrup/profiles
         | 
         | Ie. rather than a bunch of tools helping you find undefined
         | behaviour (or left-and-right improvements of what the behaviour
         | should be) you'd like to be able to make high level claims
         | about your code and have the compiler validate those
         | guarantees.
         | 
         | C++ having a huge C++ legacy, things of course are never easy.
         | So for the time being this is just work-in-progress.
        
           | pjmlp wrote:
           | First of all they have to be designed and voted in.
           | 
           | If WG21 is actually open to having them, ISO C++29 is
           | probably when they might land, then given the compiler
           | velocity with previous standards, expect at least 5 years to
           | mature, on the top three, let alone everyone else.
           | 
           | If I am not dead by then, I will certainly be retired.
           | 
           | How long will the industry be willing to wait for profiles?
        
         | tialaramex wrote:
         | I _think_ the compilers would be allowed to just make your
         | default warning changes as non-fatal diagnostics aren 't a
         | conformance matter. So you probably need to lobby GCC, Clang
         | and MSVC.
         | 
         | Herb's discussion of "unsafe" for Cpp2 is... misleading. Rust's
         | unsafe _does not turn off checking_. If you take some safe Rust
         | which compiles (even if it panics) and you just wrap that in a
         | block with the unsafe keyword, _all you get_ for your trouble
         | is a new diagnostic (by default a warning) saying not to do
         | that because it 's futile to use an unsafe block here. No
         | checks are switched off, no "performance" shortcuts are added,
         | if it would panic before it still does now - it's just the same
         | code with a frivolous "unsafe" sign on it.
        
           | jonhohle wrote:
           | Swift does this, but their release cycle is currently more
           | frequent and the roadmap is (possibly) more clear.
           | Paraphrasing:                   Warning: <Certain undesirable
           | behavior>         will be an error in Swift <Version
           | + 1>.
           | 
           | I'm not sure if it's an huge improvement, but it's easy to
           | block all forward warnings with `-Werror` to clean up right
           | away.
        
             | vlovich123 wrote:
             | both c++ and Rust emit these kind of warnings to deprecate
             | previously allowed constructs that are deemed undesirable,
             | but I don't follow how it relates to this particular topic
        
         | planede wrote:
         | > BTW. Use the AddressSanitizer. Please! The toolchain improved
         | the usage and safety of the language so much.
         | 
         | In general I agree with the sentiment, use AddressSanitizer in
         | testing/debugging. However it's not meant to be a hardening
         | option, AFAIK, so I advise against using it in production
         | (along with other sanitizers), even if you can live with the
         | performance hit.
        
       | jokoon wrote:
       | Think cell is the company the creator of lexy works at
        
         | quuxplusone wrote:
         | If you mean https://github.com/foonathan/lexy , then yes,
         | foonathan (Jonathan Muller) is literally the "I" in the first
         | sentence of TFA.
        
       | AnonSixOneTh wrote:
       | I'll say this because it needs to be said. Recently it seems like
       | every developer on LinkedIn who has "C++" in their profile, and
       | their cat, is spammed every couple of weeks by some recruiter
       | with a "great opportunity, 130,000 euros FULLY REMOTE", turning
       | out eventually to be recruiting for think-cell.
       | 
       | I got it, my friends got it, my work mates got it, everyone gets
       | spammed periodically, it has become the laughingstock of job ads.
       | 
       | Why? Read the Glassdoor reviews. The CTO is a terrorist obsessed
       | with complexity, they overengineered themselves into a corner by
       | using every freaking C++ feature that ever existed, making sure
       | that there's only 3 or 4 people in this world who can understand
       | their code. Of course the usual pattern goes: guy learns #feature
       | on-the-fly appearing both incredibly smart and embelishing his
       | resume, until of course reality hits and the complexity of the
       | crap he wrote outclasses his "genius" intellectual capacity so
       | then he leaves, leaving the mess for future hires to deal with.
       | 
       | Consequently there's maybe 3 people left in this world capable to
       | understand the atrocity that's running there, not saying fix it.
       | So good luck finding them. These people, if they exist, already
       | work for more that $130k.
       | 
       | Also, why do they need the absolute raging brinking edge of C++
       | features? What does this company do? Trillion dollar ultra low
       | latency / high throughput high frequency trading? AAA+ games
       | running on 4 x 4k monitors at 200+ fps?
       | 
       | No. They do some farty charts.
       | 
       | Again. Good luck with the recruitment! :)
        
         | lbhdc wrote:
         | That kind of sounds like a lot of code bases I have worked in.
         | Once you get some many people on a project things can get
         | messy. Perhaps its a sign they have some DX and tech debt they
         | should address.
         | 
         | As for why the latest version of c++? Personally I have found
         | the dx improvements of some of them to be worth the upgrade. I
         | really like constexpr and the build time errors it gives
         | (opposed to runtime). The newer standards let you use constexpr
         | in more places with more stl types.
        
         | CoastalCoder wrote:
         | It does make "C with classes" sound pretty appealing.
         | 
         | Well, maybe also with some very limited template facilities.
         | 
         | Shoot... Did I just describe Ada95 somewhat?
        
         | pixelpoet wrote:
         | As a C++ dev in Germany, experienced this firsthand. They make
         | you do some truly ridiculous tests, and in the end 130k isn't
         | that far off from somewhere like Maxon where you actually do
         | interesting work. Having spoken to others who applied, both in
         | person and via easily found reddit thread on r/cpp, 100%
         | certain I would have been absolutely miserable there, and
         | everyone mentions the CTO.
        
           | Rinzler89 wrote:
           | _> 100% certain I would have been absolutely miserable there,
           | and everyone mentions the CTO_
           | 
           | But..but.. think-cell says that:
           | 
           |  _" Our CTO Arno maintains a close working relationship with
           | all of our developers. Together, they review code,
           | troubleshoot, and brainstorm. Most likely due to Arno's and
           | Markus' academic roots, think-cell is flourishing without
           | program managers and lengthy meetings."_
           | 
           | Those are all the traits of a good manager and pleasant work
           | environment. And you get to work in Berlin!
        
             | intelVISA wrote:
             | > flourishing without program managers and lengthy meetings
             | 
             | EUR130k for a good C++ dev is a steal in most markets, but
             | I can see this 'perk' as a huge draw for people tired of
             | shops where "bringing key stakeholders into conversations
             | at the appropriate time" is valued over simply building
             | product.
        
               | Rinzler89 wrote:
               | _> EUR130k for a good C++ dev is a steal in most
               | markets,_
               | 
               | Most markets? Definitely not.
        
         | f1shy wrote:
         | This is the description of at least 50% of the C++ projects
         | where I was involved with. Only missing the language lawyers
         | citing paragraphs of the standard at least once a meeting.
        
           | Scubabear68 wrote:
           | Oh how I miss the language lawyers in C++. Some really
           | elevated it to a high calling. </s>
        
             | TeMPOraL wrote:
             | They got obsoleted by clang-tidy.
        
         | nuancebydefault wrote:
         | Finally somebody on HN getting attention for mentioning this
         | sad truth.
         | 
         | Usually even the least criticism on this 'holy' language [that
         | emphasizes 'intent' and glorifies people who truly understand
         | 'const correctness!' and the correct usage of dynamic_cast]
         | gets immediately downvoted.
         | 
         | The sad truth being, tons of impossible to understand code
         | bases exist in the wild, due to, for example, the mix of old,
         | less old and new memory handling strategies having been
         | applied.
        
         | SassyBird wrote:
         | Same. I and a couple of my colleagues got offers.
         | 
         | Regarding love of complexity and C++, they're sitting on the
         | C++ committee. Complexity is their bread and butter. :)
         | 
         | I also kinda doubt "Trillion dollar ultra low latency / high
         | throughput high frequency trading/AAA+ games running on 4 x 4k
         | monitors at 200+ fps" people are such enthusiasts of the
         | bleeding-edge of C++. The standard library and the style of
         | programming popular in the committee isn't very concerned with
         | high performance it seems.
        
         | nxobject wrote:
         | Truly, it's far from reassuring that the rest of think-cell's
         | developer blog is more about "modern C++" debates on style and
         | pitfalls ("Should we stop declaring functions and use global
         | constexpr lambdas instead? Consider argument-dependent
         | lookup...") than about developing their product.
        
       ___________________________________________________________________
       (page generated 2024-05-10 23:01 UTC)