13,795 karma · joined February 28, 2014
If you mean split-lock detection, it is because split locks are a massive DoS vulnerability on high core count CPUs.
I don't have a laptop with an nvidia card, but I often suspend the linux gaming machine on my living room, and sometimes it doesn't come back from sleep, while my steam deck never failed to.
struct F { double x; };
enum Op { Add, Mul };
auto eval(F x) { return x.x; }
template<class L, class R, Op op> struct Expr;
template<class L, class R> struct Expr<L,R,Add>{ L l; R r;
friend auto eval(Expr self) { return eval(self.l) + eval(self.r); } };
template<class L, class R> struct Expr<L,R,Mul>{ L l; R r;
friend auto eval(Expr self) { return eval(self.l) * eval(self.r); } };
template<class L, class R, class R2> struct Expr<Expr<L, R, Mul>, R2, Add>{ Expr<L,R, Mul> l; R2 r;
friend auto eval(Expr self) { return fma(eval(self.l.l), eval(self.l.r), eval(self.r));}};
template<class L, class R>
auto operator +(L l, R r) { return Expr<L, R, Add>{l, r}; }
template<class L, class R>
auto operator *(L l, R r) { return Expr<L, R, Mul>{l, r}; }
double optimized(F x, F y, F z) { return eval(x * y + z); }
double non_optimized(F x, F y, F z) { return eval(x + y * z); }
Optimized always generates a call to fma, non-optimized does not. Use -O1 to see the difference (will inline trivial functions, but will not do other optimizations). -O0 also generates the fma, but it is lost in the noise.The magic happens by specifically matching the pattern Expr<Expr<L, R, Mul>, R2, Add>; try to add a rule to optimize x+y*z as well.
Of course in many cases the optimization level does matter: if you are optimizing small vector operators to simd inlining will still be important.
Specifically for the European Parliament, this is also why, while it is true it doesn't have the power of legislative initiative, given the ability to amend at will any "law", in practice it doesn't make much of a difference.
Probably it is not taught as part of the curriculum in Russia.
Many EU nations are not presidential, and personally I prefer parliamentary republics than presidential ones.
But the price of freedom is indeed eternal vigilance.
I'm afraid that just C++ being C++ and you are deep into UB; you can't really modify a constexpr value at runtime, and if you cast away its constness with what is effectively a const cast you are on your own. This will print "0 3" which is obviously nonsense:
constexpr int x = 3;
((int&)x) = 0;
char y[x];
std::print("{}, {}",x, sizeof(y));
The output might change according to the compiler and optimization level.You can also move the problematic sequence into a constexpr function and invoke it in a constexpr context: the compiler will reject the cast now.
Enum constants can't become lvalues, so the following also won't compile:
enum : int { x = 3};
((int&)x) = 0;
So I guess that's closer to the rust meaning of constant.FWIW, notoriously you could modify numeric literals in early Fortrans and get into similar nonsense UB.
edit: in the end[1] it seems that you take exception with constexpr not being prvalues in C++. I guess it was found more convenient for them to have an address [1]. That doesn't make them less constant.
[1] or at least I think you do, it is not clear to me what you have been trying to claim in this discussion.
[2] C++ will materialize prvalues into temporaries when their address is needed (and give them an unique address), I guess it was thought to be wasteful for large constexpr objects, and avoids the rust pitfall you mentioned.
You could use the same trick used by glibc to implement unstoppable exceptions for POSIX cancellation: the exception rethrows itself from its destructor.
A pure library implementation that uses on normal function call semantics obviously needs to conservatively save at least all callee-save registers, but that's not the only possible implementation. An implementation with compiler help should be able to do significantly better.
Ideally the compiler would provide a built-in, but even, for example, an implementation using GCC inline ASM with proper clobbers can do significantly better.
Also, although not likely to be removed anytime soon from existing systems, POSIX has declared the context API obsolescent a while ago (it might actually no longer be part of the standard).