Readit News logoReadit News
BenFrantzDale commented on Show HN: Coros – A Modern C++ Library for Task Parallelism   github.com/mtmucha/coros... · Posted by u/singledigits
BenFrantzDale · a year ago
Have you compared perf with the reference implementation of the P2300 “Senders” proposal? https://github.com/NVIDIA/stdexec
BenFrantzDale commented on The C++ Iceberg   fouronnes.github.io/cppic... · Posted by u/thunderbong
flohofwoe · 2 years ago
std::unreachable is actually a quite useful optimisation tool. For instance if you are sure that a switch-case default branch is actually unreachable you can put a std::unreachable into the default-branch to hint the compiler that it may remove a range check in front of the switch-case jump table access (since you promised to the compiler that the default branch is never reached).

It's a double edged sword of course. If control flow actually hits the default branch, then all bets are off (because that means the code will access an out-of-range jump table slot and jump somewhere into the wilderness).

AFAIK compilers are free to perform something like Rust's panic when std::unreachable is actually hit, but that makes only sense in debug mode. Because in the above example, the compiler would need to add a range check to figure out if panic needs to be called and that would completely defeat the idea of removing that range check in the first place.

BenFrantzDale · 2 years ago
Having it available means we can use it explicitly. For example, I could see a compiler flag making `std::vector<T>::operator[]` be checked and then if profiling warrants, remove the check by explicitly checking if my index is out of bounds and invoking UB. Not saying that’s the pattern people will use, but having an escape hatch makes safer-by-default behavior more approachable.
BenFrantzDale commented on The C++ Iceberg   fouronnes.github.io/cppic... · Posted by u/thunderbong
fsloth · 2 years ago
Popularized articles about C++ are very hit or miss. It’s partly because the language is so hit and miss in it’s non-design.

The most glaring error in the iceberg IMO is the claim that shared_ptr is an antipattern.

Shared_ptr is brilliant for immutable data in parallel programs. It’s not an antipattern. It’s useless for sure as a building block for data structures and other linked data with potential for circular references.

But really, if a resource is a) immutable and b) needed in a shared context then a thin wrapper around a map of shared pointers or such saves the pain of needing to implement a much more complex resource management scheme.

BenFrantzDale · 2 years ago
As a C++ user, shared_ptr is great for some things, but it is an anti-pattern. Shared_ptr<const T> is much much better. The problem is that shared_ptr<T> isn’t value-semantic and so destroys local reasoning. That said, there are places for it, but it’s very easy to make a mess with it.

I’m a huge gain of stlab::copy_on_write<T>, which is fundamentally very similar but which is value-semantic, doesn’t let you make loops, and gives You local reasoning.

BenFrantzDale commented on Xz: Can you spot the single character that disabled Linux landlock?   git.tukaani.org/?p=xz.git... · Posted by u/dhx
dathinab · 2 years ago
It's also iffy tbh. that the compilation check functionality:

- doesn't force users to differentiate between syntax errors and other errors (e.g. symbols not found). Partially you can't even make it work properly if you want due to C macros.

- it seems sensible, tbh. if "does compile" checks for compatibility seems sensible then there is so much wrong with the ecosystem in so many ways

BenFrantzDale · 2 years ago
Agreed. I just opened https://gitlab.kitware.com/cmake/cmake/-/issues/25846 although I have no idea how hard it is to address this sort of issue robustly.
BenFrantzDale commented on The C++ Killers (Not You, Rust)   wordsandbuttons.online/th... · Posted by u/todsacerdoti
arcticbull · 2 years ago
The fact this is even a distinction anyone has to keep in mind is again an example of the problem. People are awful at remembering these weird little details. We shouldn't expect people do things they're bad at, all the time, and to get them right. And I'll go a step further and say we shouldn't let them by default. They should have to make it super explicit they want to opt into the weird behavior nobody expects.

You can do this in Rust if you want! You just have to use unsafe { mem::uninitialized() } or even better, the newer unsafe { mem::MaybeUninit::uninit() }

The whole point is that you probably don't ever want to have an uninitialized variable you can access willy-nilly, and if you do, you should be very explicit.

Even your statement about C (and C++) isn't quite accurate, right, because anything static is guaranteed to be initialized to zero on creation. So while `int x` is a free for all, `static int x` is gonna be zero. Another thing people shouldn't have to think about!

Principle of least surprise.

BenFrantzDale · 2 years ago
I agree. I wish we had to say `int x = std::uninitialized;`
BenFrantzDale commented on Talking with the inventor of C++ [video]   youtube.com/watch?v=5uA1-... · Posted by u/WoodenChair
flykespice · 2 years ago
> because it’s so flexible yet so expressive.

False, Python is much more flexible and expressive than C++

BenFrantzDale · 2 years ago
Can you express value semantics in Python, or is everything still passed by mutable reference still and duck-typed at runtime? I’m being flip, and I like Python for some things, but for large robust performant software I find C++ way easier to work with as it works with me not against me to wrangle complexity.
BenFrantzDale commented on Push ifs up and fors down   matklad.github.io/2023/11... · Posted by u/celeritascelery
dg44768 · 2 years ago
Thanks for the article. Maybe I’m confused, but why in the section near the end about how the two recommendations go together, why is the code this:

if condition { for walrus in walruses { walrus.frobnicate() } } else { for walrus in walruses { walrus.transmogrify() } } and not this?

if condition { frobnicate_batch(walruses) } else { transmogrify_batch(walruses) }

BenFrantzDale · 2 years ago
I thought that too. I think the point there was that you don’t have to push this notion as afar as in/out of functions: that just flipping them within a function can be beneficial.
BenFrantzDale commented on Push ifs up and fors down   matklad.github.io/2023/11... · Posted by u/celeritascelery
PaulDavisThe1st · 2 years ago
Contrarily:

Push ifs down:

  BAD:
    if (ptr) delete ptr;
  GOOD:
    delete ptr;
Polymorphize your fors:

  frobnicate (walrus);
  frobnicate (walruses) { for walrus in walruses frobnicate (walrus); }

BenFrantzDale · 2 years ago
I agrée with them and with you. It looks like they work in some poor language that doesn’t allow overloading. Their example of `frobnicate`ing an optional being bad made me think: why not both? `void frobnicate(Foo&); void frobnicate(std::optional<Foo>& foo) { if (foo.has_value()) { frobnicate(foo); } }`. Now you can frobnicate `Foo`s and optional ones!
BenFrantzDale commented on Formatting text in C++: Old and new ways   mariusbancila.ro/blog/202... · Posted by u/signa11
nuancebydefault · 2 years ago
I find it disappointing that cpp20 still doesn't have a solution that is more convenient than good ol printf (except for memory safety).

Another example would be convenient list comprehension, convenient maps wihout juggling around with tuples, first(), second(), at()...

BenFrantzDale · 2 years ago
For list comprehension, we have (C++23): `std::ranges::to<std::vector>(items | std::views::filter(shouldInclude) | std::views::transform(f))` it’s not quite `[f(x) for x in items if shouldInclude(x)]` but it’s the same idea.
BenFrantzDale commented on Linear code is more readable   blog.separateconcerns.com... · Posted by u/dmarto
gorgoiler · 2 years ago
Another risk is if you add print_table() then someone else is going to find it and use it in their code, but also add a little flag to adjust the output for their use case.

12 months later you have:

  print_table(
    rows,
    headers = None,
    is_unicode = False,
    left_align = False,
    align = [],
    remove_emoji = None,
    max_width = 80,
    potato_mode = 7,
    _debug_frontend = not FLAGS.dont_debug,
    ellipsis_for = 0,
    no_print = False,
  )

BenFrantzDale · 2 years ago
That’s what tests are for. And if `print_table` is factored properly then they won’t want to add flags, they’ll make a new function out of the pieces of `print_table` that has distinct behavior of its own.

u/BenFrantzDale

KarmaCake day346August 19, 2014View Original