boring c++ porn
While I could maybe chase after this to a potential bug report, I think it wouldn't be taken seriously, especially if I'm pressed on a use case, which I myself consider dubious. It's also somewhat indicative that maybe my approach was not necessarily the best for this kind of an experiment. I went with forwarding, in my implementation of visit_first, since that's the standard for any kind of transparent wrapper function that's supposed to entirely disappear in most cases. Being a c++ standard however it has to handle references well, that can be used as mutable out parameters sometimes (the heresy!) and that is likely the crux of the problem. References to local variables make the job of the compiler much harder, so we're going to go with another common pattern, explicit value and move semantics - pass everything by value, use std::move to avoid copies. Getting rid of mutable references simplifies things quite a bit, but in general has a nuanced cost of the move constructor (though I might not be able to use any moveable objects either, due to non-trivial destructors, and have to stick with trivial value types).
This puts me back on track with gcc-10.2 now properly optimizing all the calls. Unfortunately this also means that visit_first is no longer a generic library function, it will have to stay in this project forever, and no longer living up to its current name, instead become funky_visit:
https://git.sr.ht/~namark/funky/commit/5e440f00d59cccd4b1dd66e6bf288e73314c7408
Also seems like clang doesn't do tail call optimization well unless you change the calling conventions (whatever that entails), so it's a win-win!
boring c++ porn
of course gcc 10.2 doesn't optimize my visit first anymore... it does if I inline it manually though... what is this regression? T_T