15
Comments
  • 8
    🫡
  • 13
    What part of Option<Arc<Vec<Option<dyn Foobar + Send>>>> did you not understand
  • 9
    @12bitfloat add three more nesting levels to unlock “Git Conflict Markers Are Now Valid Rust” achievement
  • 3
    C++ accommodates zero-cost better. Rust is a lot easier if you ppermit sacrificing some pperformance in the interest of convenience, for example by returning trait objects when you could technically spell out a ridiculous, 10 lines long concrete type.
  • 4
    Then again, C++ doesn't really have third party impls so interoppperability always must hhappen through an additional object. I honestly don't know enough about it to determine whether this is a problem.
  • 4
    @lorentz I mean... you could also just use a type alias

    C++ and Rust are really similar when it comes to generated machine code. Both are suboptiomal for a lot of very specific reasons

    In Rust for example a for loop over an inclusive range like 1..=10 can be quite a bit slower since it has to guard against overflow

    In C++ you can get bad codegen if you use std::move where you shouldn't because I think that prevents named return value optimization

    Fun!
  • 2
    @lorentz

    C++ does have "third party" implementations, in the sense that the committee only defines the language, it doesn't implement anything. And oh boy shit will happen if you try and mix different g++, msvc++ and clang.

    However I think the "competition" results in better implementations.

    @12bitfloat

    Compilers nowadays are smart enough to prevent those footguns, since it's easy to statically determine when something acts as a rvalue, and will always perform RVO when possible even if you do retarded shit.

    std::move is just a lexicographically fancy static_cast<T&&>(), which doesn't really have any implications for auto variables.

    The problem, as always, is people wanting to write fancy code and not knowing what they are doing.

    Cppreference explicitly states that manually using std::move is, 99% of the time, a mistake, and hence compilers try to protect you from it.
  • 1
    @CoreFusionX hmm, I used it once quite long ago, don't remember the use case. But not a c++ expert in general. Not a big fan.
  • 0
    Also, while not really being an example of zero cost abstractions, I love that c++'s *runtime* safety is opt-in.

    Shit like iterator/range checking is done by pretty much all major c++ runtimes... When using their debug version.

    Not a fan of paying for that shit in release mode.
  • 1
    @retoor

    The use case is really making sure you get a rvalue reference to whatever you will be requesting to move (really std::move should have been called std::rvalue_ref_cast), because you intend to pass it to (possibly external) other code that might optimize based on copy or move semantics.

    However, except very few and far corner cases, good library implementors will either

    - explicitly delete copy or move semantics where they don't make sense, resulting in an error if you try to use them.

    - just take a const lvalue reference, and let compiler do its magic (99% of the time better than what you intend to do)

    - do perfect forwarding if it's just forwarding to other code, delegating to problem to the callee.

    Only in the second case, if for whatever reason a const T& would violate const correctness and you'd need to take a T& or T&& explicitly, would a manual std::move make sense.

    I have seen it only once in app (as in, not library) code.
  • 1
    @CoreFusionX I really needed it because it didn't work some other way iirc. It wasn't to be fancy or optimaztion. Really needed.
  • 1
    @12bitfloat That's really interesting, I assumed that if it's really that expensive they would just check the max value before entering the loop.
  • 1
    Especially with iterators being such well-defined distinct values with lifetimes and immutability guarantees, such an optimization doesn't sound very difficult. But maybe I'm oversimplifying.
  • 1
    @CoreFusionX The compiler can't always prevent stuff like that since sometimes it's in the semantics of the program

    E.g. if you return a string as const, the compiler HAS to copy it, it can't move from it
  • 0
    @lorentz LLVM apparently sucks at optimizing it and Rust hasn't put any effort in optimizing it at the IR stage

    But yeah, it really shouldn't be too difficult
  • 1
    @12bitfloat

    It has to copy if you create a const string inside the function body and then you return it.

    Having const as return type and returning an auto non const object won't invalidate RVO.

    Problem is, again, people not understanding the mechanism and just sprinkling const everywhere because they read it in some trend blog, just like sprinkling std::move around.
  • 0
    @CoreFusionX Sure, but that's what I'm saying. Both Rust's and C++'s zero cost abstractions aren't always zero cost if you don't know how to use them properly
Add Comment