The main big philosophical difference regarding templates is that Rust wants to guarantee that generic instantiation always succeeds; whereas C++ is happy with instantiation-time compiler errors. The C++ approach does make life a fair bit easier and can maybe even avoid some of the lifetime annotation burden in some cases: in Rust, a generic function may need a `where T: 'static` constraint; in C++ with lifetimes it could be fine without any annotations as long as it's never instantiated with structs containing pointers/references.
Template specializations are not in Rust because they have some surprisingly tricky interactions with lifetimes. It's not clear lifetimes can be added to C++ without having the same issue causing safety holes with templates. At least I think this might be an issue if you want to compile a function instance like `void foo<std::string_view>()` only once, instead of once for each different string data lifetime.
The really horrible bufferfloat usually happens when the upload bandwidth is saturated -- upload bandwidth tends to be lower so it'll cause more latency for the same buffer size.
I used to have issues with my cable modem, where occasionally the upload bandwidth would drop to ~100kbit/s (from normally 5Mbit/s), and if this tiny upload bandwidth was fully used, latency would jump from the normal 20ms to 5500ms. My ISP's customer support (Vodafone Germany) refused to understand the issue and only wanted to upsell me on a plan with more bandwidth. In the end I relented and accepted their upgrade offer because it also came with a new cable modem, which fixed the issue. (back then ISPs didn't allow users to bring their own cable modem -- nowdays German law requires them to allow this)
> You can send half-random input in and then send more half-random input in until you’re satisfied that the RNG has gotten a suitable amount of entropy.
This does not actually work. If an attacker can observe output of the CSPRNG, and knows the initial state (when it did not yet have enough entropy), then piecemeal addition of entropy allows the attacker to bruteforce what the added entropy was.
To be safe, you need to add a significant amount of entropy at once, without allowing the attacker to observe output from an intermediate state. But after you've done that, you won't ever need to add entropy again.
In my experience, C++ template usage will always expand until all reasonably available compile time is consumed.
Rust doesn't have C++'s header/implementation separation, so it's easy to accidentally write overly generic code. In C++ you'd maybe notice "do I really want to put all of this in the header?", but in Rust your compile times just suffer silently.
On the other hand, C++'s lack of a standardized build system led to the popularity of header-only libraries, which are even worse for compile times.
You can still install Windows 11 without a Microsoft account.
It requires configuring the installation before you boot from the USB stick.
I use https://rufus.ie/en/ when creating bootable USB sticks, and it turns out that this tool detects when you're trying to create a Windows installation medium, and prompts with a list of useful customizations, including "Remove requirement for online Microsoft account". (if you look through the screenshots on the webpage, there's one with the Windows customization dialog box)
I've used this many times myself and it works great.
However, as I mentioned below, I read something recently that says local account options are being removed in an upcoming version (I can't find the article now).
I presume it means the binaries are being removed from the ISO so this may no longer work (except for Enterprise and LTSC I'd imagine).
I still haven't seen anywhere reporting what, exactly, was the issue, and why would using the "true Administrator" account on Windows (or using Linux) avoid the issue.
My own uninformed guess, given that the "true Administrator" account avoids it, would be some sort of security mitigation, for instance flushing the branch predictor state when entering or exiting the kernel unless the current user is SYSTEM or Administrator.
If you have a hot path with a lot of branch mispredictions that can impact performance. Could be as simple as Microsoft found a dumb if inside a tight loop.
However Windows has stacks that commit on-demand, which is kinda similar to overcommit. It can result in programs terminating on any random function call (if that call requires allocating a new page of stack).
https://learn.microsoft.com/en-us/windows/win32/procthread/t...
However this is very rare to happen in practice -- stack growth isn't very frequent in typical applications; so usually a malloc() will fail first in low-memory situations.
A Windows program can avoid the risk of getting terminated on stack growth by specifying equal commit and reserve sizes for the stack. So in least in theory, it's possible to write a windows program that is reliable in low memory situations.
But if you're on 64-bit; you can just create the threads with a huge stack size limit (e.g. 1GB) and let the OS handle automatically growing the actual stack size. No need to reinvent the wheel.
That's no longer true: https://www.intel.com/content/www/us/en/developer/articles/t...
x86 hardware does not guarantee anything unless you enable "Data Operand Independent Timing Mode", which is disabled by default and AFAIK can only be enabled by kernel-level code. So unless operating systems grow new syscalls to enable this mode, you're just out of luck on modern hardware.
In the most purely theoretical sense, you are correct, but everything Intel and AMD has said indicates they will still offer strong guarantees on the DOIT instructions:
In other words, they have announced the possibility of breaking that guarantee years before touching it, which is something the clang developers would never do.
Template specializations are not in Rust because they have some surprisingly tricky interactions with lifetimes. It's not clear lifetimes can be added to C++ without having the same issue causing safety holes with templates. At least I think this might be an issue if you want to compile a function instance like `void foo<std::string_view>()` only once, instead of once for each different string data lifetime.