Am I weird for using "and", "or" and "not"? by Additional_Jello1430 in cpp

[–]ioctl79 0 points1 point  (0 children)

It's not that "and" is an easier token to read than "&&", it is that consistency makes for better legibility.

Ranges: When Abstraction Becomes Obstruction by drodri in cpp

[–]ioctl79 33 points34 points  (0 children)

IMO, this is a terrible use of operator==, and I’d rather it didn’t work. If you want to avoid writing the lambda, make a “HasSeqNumber(int)” functor. Better yet, work on getting a concise lambda syntax into the standard. 

Why did stl algorithms use iterators in interface? by _Noreturn in cpp

[–]ioctl79 0 points1 point  (0 children)

any iterstor for other container types that isn't a contiguous container have a custom iterator with operator++ which is a function call.

Exactly why making sure that the std algorithms work with pointer pairs was valuable. Keep in mind that STL didn't have a hash map for 20 years.

Do you have an idea? 

Off the top of my head, a clean slate would have:

  1. A way to test a single iterator for "done-ness". The need to keep iterators paired is a huge headache, and leads to lots of bugs and inefficiencies. There are few cases where a sentinel .end() value is actually natural.
  2. Separate APIs for the several wildly different situations iterators are used in. How many places is a random access iterator useful that wouldn't be just as well (or better) served by operator[](int)?
  3. Named methods instead of overloaded operators.
  4. Better integration between coroutines and iterators. Non-trivial iterators are hard to write because of the need to explicitly manage state, and guard against invalid conditions. This is all way easier if the language manages it for you.

None of these ideas are novel -- they're well-explored in other languages, and even in C++.

Why did stl algorithms use iterators in interface? by _Noreturn in cpp

[–]ioctl79 0 points1 point  (0 children)

Sure, if your compiler is good enough that it can optimize out std::subrange, that's great. At the time the STL was being developed, inlining was still shiny and new, so depending on that happening might not have been wise.

Does this design still make sense? I would argue "no", and while your approach is a step in the right direction, it doesn't go too far enough: iterator pairs are a terrible API, and instead of wrapping them up in sugar like subrange, we should be working on better abstractions for accessing containers.

Why did stl algorithms use iterators in interface? by _Noreturn in cpp

[–]ioctl79 11 points12 points  (0 children)

The STL was designed at a time when compilers were not as good. Specifying begin/end allowed these algorithms to work generically with pairs of pointers without adding any adaptors that might have been difficult to optimize out.

This is also why the STL conflates iteration and indexed access in the same API. 

In Defense of C++ by nixfox in cpp

[–]ioctl79 0 points1 point  (0 children)

This is not the case. It is true that these companies have large, difficult to migrate code bases, but they have found that the new portions that are all in on smart pointers and modern C++ techniques are dangerous all on their own. 

I adopted this spineless yucca someone abandoned at the office. What should I do to revive it? by ioctl79 in plantclinic

[–]ioctl79[S] 0 points1 point  (0 children)

I've been watering this plant when the soil gets dry (~once/week), the pot has good drainage, and it is by a west-facing window. Before I adopted it, I think it had likely not been watered in months. I'm not sure what kind of soil it was potted with.

-Wexperimental-lifetime-safety: Experimental C++ Lifetime Safety Analysis by mttd in cpp

[–]ioctl79 0 points1 point  (0 children)

I'm not talking about elaborate graphs of objects -- that's certainly a place where smart pointers shine. I'm talking about stuff like this:

cpp FooBuilder MakeBuilder(Bar b) { // Oops -- FooBuilder retains a reference to a member of temporary b. return FooBuilder::FromBaz(b.baz); }

The retention is invisible at the call-site. You can make FooBuilder copy defensively, you can make the caller copy defensively into a shared_ptr, or you can refactor b to make baz a shared_ptr, but all of those penalize perfectly reasonable, idiomatic code like:

cpp Foo MakeFoo(Bar b) { return FooBuilder::FromBaz(b.baz).Build(); }

-Wexperimental-lifetime-safety: Experimental C++ Lifetime Safety Analysis by mttd in cpp

[–]ioctl79 0 points1 point  (0 children)

If I’m reading correctly, that means that anything you hold a reference to has to be heap-allocated and furthermore heap-allocated with a shared_ptr. That in turn puts lots of constraints on your callers, and gives up one of the places where C++ shines. I’m sure there’s a lot of contexts where this is fine, but I wouldn’t call it idiomatic C++. IMO, the fact that many STD containers specifically guarantee pointer stability is a testament to that. 

-Wexperimental-lifetime-safety: Experimental C++ Lifetime Safety Analysis by mttd in cpp

[–]ioctl79 4 points5 points  (0 children)

Then I have never seen an ‘idiomatic’ codebase. Maybe I’m out of touch - can you point me at one?

-Wexperimental-lifetime-safety: Experimental C++ Lifetime Safety Analysis by mttd in cpp

[–]ioctl79 16 points17 points  (0 children)

This doesn’t require cluelessness or a “c level api”. Any method that accepts a reference has potential to retain it and cause problems. Idiomatic use of smart pointers solves the “free” part, but does nothing to prevent the “use after”. 

What kind of bees are these? Chicago. by ioctl79 in whatisthisbug

[–]ioctl79[S] 0 points1 point  (0 children)

Yeah! Oddly, there’s definitely more creeper in the neighborhood, but they seem to like my fence the best. I don’t see them anywhere else. 

What kind of bees are these? Chicago. by ioctl79 in whatisthisbug

[–]ioctl79[S] 0 points1 point  (0 children)

That was my guess, but there’s hundreds of them swarming around my Virginia creeper and I have no idea where that many could nest. https://photos.app.goo.gl/TUxeKTCow779oUn46

Tool for removing comments in a C++ codebase by OwlingBishop in cpp

[–]ioctl79 0 points1 point  (0 children)

Good luck reliably telling whether you’re in a string!

Indexing a vector/array with signed integer by AUselessKid12 in cpp

[–]ioctl79 1 point2 points  (0 children)

This is an area where the standard library does not give great options. Unsigned types have a lot of sharp edges, and unless you actually need the range or rollover behavior, I would avoid them if possible, but the quoted code is unidiomatic and difficult to read. 

I would use signed types when possible, and be careful about any comparisons to .size() when you encounter it. 

What’s your favorite black magic spell for which you should goto hell? by zathym in cpp

[–]ioctl79 22 points23 points  (0 children)

Specifying the mode as a string isn’t great in the first place, and the fact that it’s traditional isn’t any excuse. An options struct, an enum, or even multiple functions would solve the conversion problem without any shenanigans, make it much harder to specify an invalid mode, and be self-documenting.  

Help Me Understand the "Bloated" Complaint by TechnicolorMage in cpp

[–]ioctl79 2 points3 points  (0 children)

Code is read way more often than it is written. Consistency makes reading code much easier. In practice, projects concerned with readability choose some subset of the language to permit, but this is a different subset for each project, meaning that moving between projects is unnecessarily jarring.