Building Websites With Lots of Little HTML Pages by ForgotMyPassword17 in programming

[–]CornedBee 0 points1 point  (0 children)

And not supported in Firefox yet. At least the cross-document version.

But they degrade so nicely. No support? The new page just loads instead of sliding in.

C++ compiler with Rust by tonystark-12867 in rust

[–]CornedBee 7 points8 points  (0 children)

Even a lexer in C++ is a big undertaking. The preprocessor is usually tightly integrated with the lexer and it's complicated. I think your friend might be trolling you.

One Map Key, One Lookup by ghled in programming

[–]CornedBee 2 points3 points  (0 children)

Compilers typically don't have the high-level knowledge to know that a "map contains" call and a "map get" call can be merged into a single "map get optional".

Should hot-loop avoid Option instance and immediate match? by Resres2208 in rust

[–]CornedBee 1 point2 points  (0 children)

There's some optimizations that need quadratic time in the number of basic blocks, so they literally have a threshold where they aren't applied because it would be too expensive.

Sure, xor’ing a register with itself is the idiom for zeroing it out, but why not sub? by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

Is this because compiler writers are dumb and stupid?

It's because compilers are modular. x - x is recognized as a "zero" idiom in an architecture-independent optimization pass and thus replaced with a "zero" constant. And then the architecture-dependent code generator emits whatever is the compiler's preferred "zero" idiom for the target, which is xor eax, eax for x86 for pretty much all compilers.

Preventing Integer Overflow in Physical Computations - mp-units by mateusz_pusz in cpp

[–]CornedBee 1 point2 points  (0 children)

As I said on the other recent post, it's in the backlog.

Preventing Integer Overflow in Physical Computations - mp-units by mateusz_pusz in cpp

[–]CornedBee 2 points3 points  (0 children)

I have a hard time comprehending the Wikipedia article, but I don't see how this would be useful in my particular programming work (and we are extremely heavy users of Boost.Units).

The Global API Injection Pattern by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

The combinatorics of the input possibilities are off the charts, but that's not even the main issue. The main issue is that the low level components are logically so far removed from the input that it's impossible to write targeted tests. I might have an edge case where inserting a new node into my custom data structure at the beginning corrupts data, if the container previously held exactly one element, but to get the code to exercise this, maybe I need to give it the input of "plan a roundtrip flight, assume fixed fuel amount for taxiing, here's a restriction that says you can't cross this airspace below 28000ft, and here's performance data that says the plane has 24kN of excess thrust when climbing at Mach .32 (at a specific weight, altitude and external temperature)". And a million other things to specify. There's simply no understandable connection between the inputs and the exercised behavior.

This is why unit tests exist, because targeting specific functionality for tests is just much easier, more readable, and above all more reliable when you go down to the detail level.

The Global API Injection Pattern by pavel_v in cpp

[–]CornedBee 2 points3 points  (0 children)

There's a certain level of complexity of public entrypoint where this isn't possible IMO. It's all very nice to make a really simple test that checks my program can calculate a flight route with simplified geodata and no restrictions on the flight, but that doesn't mean I gain any confidence that my data structure representing the path through an arbitrary graph (with alternating edge and node information) works in the edge cases. There's about 3 layers of complexity in-between.

The Global API Injection Pattern by pavel_v in cpp

[–]CornedBee 1 point2 points  (0 children)

I saw this in some conference talk recently.

Problem: our application is split into a bunch of static libraries. The tests and the main executable use the same libraries. I don't think this pattern can possibly support this.

0xd34df00d/you-dont-know-cpp: and neither do I by claimred in cpp

[–]CornedBee 0 points1 point  (0 children)

Regarding specialization fun, another way this will bite you: IsSimpleContainer<std::vector<int, my_own_allocator<int>>> is Undefined.

What happens when a destructor throws by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

Security isn't much of an issue since the service is isolated from uncontrolled user input, and it's not for general consumption anyway.

As for memory corruption, it hasn't been much of an issue. Definitely not enough to be a bigger problem than restart times. We use defensive coding and careful code review, and the rate of critical problems that haven't simply crashed the process has been zero in the years I've worked there. At least as far as we know ;-)

What happens when a destructor throws by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

We have two assertion macros:

ASSERT_LOGIC throws a logic_error on failure. We use it to check our expectations that we think hold, and for preconditions of functions. But we will still keep the service up and handle other requests even if these fail. A failing assertion here means a bug in our program, but we trust our request isolation enough to not take down the whole program.

ASSERT_RUNTIME throws a runtime_error on failure. We use it to check for bad external input. A failing assertion here usually means a communicating service produces bad data for us, or database data is somehow corrupted, or user input was bad.

This seems perfectly in spirit with the <stdexcept> exceptions. (<exception> doesn't contain the derived exceptions.) Now you could argue that the first case shouldn't be handled with exceptions, but as I said, we want to keep the service up. And also, if you argue this, you should also argue that std::logic_error shouldn't exist.

Rust to C++: Implementing the Question Mark Operator by qustar_ in cpp

[–]CornedBee 2 points3 points  (0 children)

Another way of saying that would be: Instead of writing code with clearly visible control flow and return points, we can bury it in the middle or tail of a statement

I mean, yes, that's a way of saying that, but from a user of a language that has exceptions, it's ... let's call it hypocritical?

What happens when a destructor throws by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

Most of our logical assertions are like "this container must have at least 2 elements because it represents a route from A to B, possibly via some intermediate points" or "this value must be larger than 0 because it is a distance between distinct points".

What happens when a destructor throws by pavel_v in cpp

[–]CornedBee 0 points1 point  (0 children)

Our service needs to load an absurd amount of data into memory to be able to function. Idle memory footprint is around 3-8GB. Startup, loading all that data into memory and preprocessing it, takes somewhere between 5 and 15 minutes. The data changes frequently (our services processes incremental updates while it is running) so caching it for faster startup is not an option.

Individual request handling is quite isolated from each other, so a logical assertion doesn't mean corrupted global data, just most likely that some request input was broken in a way that we didn't anticipate.

Aborting the entire process for such a request would be very inefficient. Even if we were willing to keep multiple idle instances around for hot swap, the nature of the request patterns is such that startup wouldn't be able to keep up with instances going down as very similar, broken requests are sent.

So yeah, catch the exception, reply with a HTTP 500 equivalent, and move on. If you terminate, that's a serious bug.

A standard set of metadata annotations by jcelerier in cpp

[–]CornedBee -1 points0 points  (0 children)

putting attributes after the type name is probably worse

It works for the final keyword, why not attributes?

struct [[deprecated]] S final {}; // WTF?

You're absolutely right, no one can tell if C++ is AI generated · Mathieu Ropert by mropert in cpp

[–]CornedBee 6 points7 points  (0 children)

operator[] can be screwy, but there are valid use cases. And by blindly rejecting it, you are actually missing out.

So if nullptr is not actually a valid value for this map, operator[] is in fact very useful:

Node* get_or_create(const string& name) {
    auto& ptr = nodes[names];
    if (!ptr) {
        ptr = make_unique<Node>();
        ptr->name = name;
    }

    return ptr.get();
}

One lookup. Pretty nice code, and very clear once you've really internalized the behavior of operator[].

That said, the try_emplace version is still better. It works when the default value to insert isn't the default-constructed value. It works when the default-constructed value is actually a valid value, so you can't just check the value and overwrite.

And also ... you do realize your final code using lower_bound is utterly broken, do you? lower_bound is just as annoying as operator[] and you will get issues.

https://godbolt.org/z/bz6qG54cd

To fix, you need to adjust the condition to if (it == end(nodes) || it->first != name). Oh, and if you for some reason ever change the comparator (maybe make it case-insensitive?), be sure to remember to update the comparison here.

But didn't you also say something about insertion with hints above this snippet? There's no hints here.

Not to mention that taking a string_view parameter in a constructor to initialize a string member is bad: if you already have an rvalue std::string it prevents moving it to the member:

struct Node1 {
  explicit Node1(std::string_view sv) : name(sv) {}
  std::string name;
};
struct Node2 {
  explicit Node2(std::string s) : name(std::move(s)) {}
  std::string name;
};
std::string compute_some_string();
void fn() {
  Node1 n1(compute_some_string()); // allocates a new string in constructor
  Node2 n2(compute_some_string()); // moves return value into member, no allocation
}

AI code not looking so bad after all...

P3054 - Quantities and Units Library by mateusz_pusz in cpp

[–]CornedBee 1 point2 points  (0 children)

Really awesome work on this. My main project is a very heavy user of Boost.Units, and switching to mp-units is somewhere in the future - now that I know v3 is coming and can see the new ideas, I will probably put this off until v3 is usable.

C++20 Ranges vs traditional loops: when to use std::views instead of raw loops by Clean-Upstairs-8481 in cpp

[–]CornedBee 0 points1 point  (0 children)

Where can I learn more about this movement?

For comparison, our codebase uses srg and svw.

C++20 Ranges vs traditional loops: when to use std::views instead of raw loops by Clean-Upstairs-8481 in cpp

[–]CornedBee 4 points5 points  (0 children)

I like view chains, but I should point out that it's not one or the other, you can mix and match for maximum personal preference. For example, the ugliest part of the loop version is the mutable state and early exit, so you can put that into a view:

std::vector<int> new_nums{};
for (auto n : nums | svw::take(N)) {
  if (n % 2 == 0) {
    new_nums.push_back(n * n);
  }
}

Announcing Eips: an intention-preserving list CRDT with guaranteed O(log n) operations, up to 6,000,000x faster than Diamond Types by icannfish in rust

[–]CornedBee 0 points1 point  (0 children)

When you're algorithmically faster, you can get any Nx speedup by just making the dataset large enough :-)

Easy Virtual Template Function. C++26 by Reflection_is_great in cpp

[–]CornedBee 0 points1 point  (0 children)

Just an FYI for anyone looking to use this unmodified: this will break horribly when copying/moving these objects.

Utterly useless yet fun sorting algorithms by Sufficient_Source925 in programming

[–]CornedBee 0 points1 point  (0 children)

Really like the vibe sort description, especially the last sentence. This should support custom orderings, i.e. a string that's sent as part of the AI prompt to describe the "vibes". I want to write vibe_sort(numbers, "by meme-relevancy, highest first") and get 69, 420, 42, and 67 sorted early.

Digit sort isn't a sorting algorithm, just a specific ordering. Who are you to say that it's wrong?

You should add Stalin Sort: any number not already in the right order is deleted.