<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: dgrunwald</title><link>https://news.ycombinator.com/user?id=dgrunwald</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 14 May 2026 15:26:35 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=dgrunwald" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by dgrunwald in "Shell Tricks That Make Life Easier (and Save Your Sanity)"]]></title><description><![CDATA[
<p>It's a normal command called "View: Reopen Closed Editor".</p>
]]></description><pubDate>Thu, 26 Mar 2026 11:26:09 +0000</pubDate><link>https://news.ycombinator.com/item?id=47529172</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47529172</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47529172</guid></item><item><title><![CDATA[New comment by dgrunwald in "NaN Is Weird"]]></title><description><![CDATA[
<p>Yes `int` acts as if it was a subtype of `float`: <a href="https://typing.python.org/en/latest/spec/special-types.html#special-cases-for-float-and-complex" rel="nofollow">https://typing.python.org/en/latest/spec/special-types.html#...</a></p>
]]></description><pubDate>Sun, 15 Mar 2026 12:45:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=47386882</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47386882</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47386882</guid></item><item><title><![CDATA[New comment by dgrunwald in "NaN Is Weird"]]></title><description><![CDATA[
<p>But in Python the type checker does not complain about `x: float = 0`, because for the purpose of type checking (but not at runtime), `int` is considered a subtype of `float`: <a href="https://typing.python.org/en/latest/spec/special-types.html#special-cases-for-float-and-complex" rel="nofollow">https://typing.python.org/en/latest/spec/special-types.html#...</a></p>
]]></description><pubDate>Sun, 15 Mar 2026 12:44:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=47386877</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47386877</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47386877</guid></item><item><title><![CDATA[New comment by dgrunwald in "NaN Is Weird"]]></title><description><![CDATA[
<p>In most languages, `x: float = 0` involves an implicit conversion from int to float. In Python, type annotations have no impact on runtime behavior, so even though the type checker accepts this code, `type(x)` will be `int` -- python acts as if `int` was a subtype of `float`.<p>It would be weird if the behavior of `1 / x` was different depending on whether `0` or `0.0` was passed to a `x: float` parameter -- if `int` is a subtype of `float`, then any operation allowed on `float` (e.g. division) should have the same behavior on both types.<p>This means Python had to choose at least one:<p>1. division violates the liskov substitution principle<p>2. division by zero involving only integer inputs returns NaN<p>3. division by zero involving only float inputs throws 
exception<p>4. It's a type error to pass an int where a float is expected.<p>They went with option 3, and I think I agree that this is the least harmful/surprising choice. Proper statically typed languages don't have to make this unfortunate tradeoff.</p>
]]></description><pubDate>Thu, 12 Mar 2026 20:45:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=47356840</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47356840</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47356840</guid></item><item><title><![CDATA[New comment by dgrunwald in "Rust is just a tool"]]></title><description><![CDATA[
<p>Don't forget the compatibility issues: Fil-C isn't really usable if you mix C with other languages in the process.<p>It's especially problematic to have multiple different garbage collectors; so given the desire to reuse libraries across language boundaries, there's still a strong demand for Yolo-C, C++ or Rust.</p>
]]></description><pubDate>Sat, 28 Feb 2026 20:56:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=47200141</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47200141</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47200141</guid></item><item><title><![CDATA[New comment by dgrunwald in "Index, Count, Offset, Size"]]></title><description><![CDATA[
<p>When accessing individual elements, 0-based and 1-based indexing are basically equally usable (up to personal preference).
But this changes for other operations! For example, consider how to specify the index of where to insert in a string. With 0-based indexing, appending is str.insert(str.length(), ...). With 1-based indexing, appending is str.insert(str.length() + 1, ...).
Similarly, when it comes to substr()-like operations, 0-based indexing with ranges specified by inclusive start and exclusive end works very nicely, without needing any +1/-1 adjustments. Languages with 1-based indexing tend to use inclusive-end for substr()-like operations instead, but that means empty substrings now are odd special cases.
When writing something like a text editor where such operations happen frequently, it's the 1-based indexing that ends up with many more +1/-1 in the codebase than an editor written with 0-based indexing.</p>
]]></description><pubDate>Sat, 21 Feb 2026 14:52:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=47101368</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=47101368</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47101368</guid></item><item><title><![CDATA[New comment by dgrunwald in "Microsoft gave FBI set of BitLocker encryption keys to unlock suspects' laptops"]]></title><description><![CDATA[
<p>> make sure not to sign into your Microsoft account or link it to Windows again<p>That's not so easy. Microsoft tries really hard to get you to use a Microsoft account. For example, logging into MS Teams will automatically link your local account with the Microsoft account, thus starting the automatic upload of all kinds of stuff unrelated to MS Teams.<p>In the past I also had Edge importing Firefox data (including stored passwords) without me agreeing to do so, and then uploading those into the Cloud.<p>Nowadays you just need to assume that all data on Windows computers is available to Microsoft; even if you temporarily find a way to keep your data out of their hands, an update will certainly change that.</p>
]]></description><pubDate>Fri, 23 Jan 2026 19:35:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=46736784</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=46736784</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46736784</guid></item><item><title><![CDATA[New comment by dgrunwald in "How we made Python's packaging library 3x faster"]]></title><description><![CDATA[
<p>That loop isn't N²: if there are long sequences of dashes, every iteration will cut the lengths of those sequences in half. So the loop has at most lg(N) iterations, for a O(N*lg(N)) total runtime.</p>
]]></description><pubDate>Tue, 20 Jan 2026 11:51:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=46690859</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=46690859</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46690859</guid></item><item><title><![CDATA[New comment by dgrunwald in "Why is Zig so cool?"]]></title><description><![CDATA[
<p>cygwin is a POSIX-emulating library intended for porting POSIX-only programs to Windows.
That is: when compiling for cygwin, you'd use the cygwin POSIX APIs <i>instead of</i> the Windows APIs. So anything compiled with cygwin won't be a normal Windows program.<p>There's no reason to use cygwin with Rust, since Rust has native Windows support. The only reason to use x86_64-pc-cygwin is if you would need your program to use a C library that is not available for Windows, but is available for cygwin.<p>If you don't want to/can't use the MSVC linker, the usual alternative is Rust's `x86_64-pc-windows-gnu` toolchain.</p>
]]></description><pubDate>Sat, 08 Nov 2025 10:56:25 +0000</pubDate><link>https://news.ycombinator.com/item?id=45855805</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=45855805</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45855805</guid></item><item><title><![CDATA[New comment by dgrunwald in "Why is Zig so cool?"]]></title><description><![CDATA[
<p>If you need `0..=n`, you can't write `0..(n+1)` because that addition might overflow.</p>
]]></description><pubDate>Sat, 08 Nov 2025 10:33:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=45855706</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=45855706</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45855706</guid></item><item><title><![CDATA[New comment by dgrunwald in "The provenance memory model for C"]]></title><description><![CDATA[
<p>But the source character set remains implementation-defined, so compilers do not have to directly support unicode names, only the escape notation.<p>Definitely a questionable choice to throw off readers with unicode weirdness in the very first code example.</p>
]]></description><pubDate>Mon, 30 Jun 2025 12:30:20 +0000</pubDate><link>https://news.ycombinator.com/item?id=44422453</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=44422453</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44422453</guid></item><item><title><![CDATA[New comment by dgrunwald in "Making C and Python Talk to Each Other"]]></title><description><![CDATA[
<p>The article is using the Python C API directly.<p>pybind11 is a C++ wrapper that makes the Python API more friendly to use from C++ (e.g. smart pointers instead of manual reference counting)</p>
]]></description><pubDate>Fri, 30 May 2025 08:59:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=44134294</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=44134294</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44134294</guid></item><item><title><![CDATA[New comment by dgrunwald in "Exploiting Undefined Behavior in C/C++ Programs: The Performance Impact [pdf]"]]></title><description><![CDATA[
<p>> But if i is indeed put immediately after, then the function should indeed return 5 for n=3.<p>That's not how compilers work. The optimization changing `return i;` into `return 0;` happens long before the compiler determines the stack layout.<p>In this case, because `return i;` was the only use of `i`, the optimization allows deleting the variable `i` altogether, so it doesn't end up anywhere on the stack. This creates a situation where the optimization only looks valid in the simple "flat memory model" because it was performed; if the variable `i` hadn't been optimized out, it would have been placed directly after `arr` (at least in this case: <a href="https://godbolt.org/z/df4dhzT5a" rel="nofollow">https://godbolt.org/z/df4dhzT5a</a>), so the optimization would have been invalid.<p>There's no infrastructure in any compiler that I know of that would track "an optimization assumed arr[3] does not alias i, so a later stage must take care not to place i at that specific point on the stack". Indeed, if array index was a runtime value, the compiler would be prevented from ever spilling to the stack any variable that was involved in any optimizations.<p>So I think your general idea "the allowable behaviors of an out-of-bounds write is specified by the possible actual behaviors in a simple flat memory model for various different stack layouts" could work as a mathematical model as an alternative to UB-based specifications, but it would end up not being workable for actual optimizing compiler implementations -- unless the compiler could guarantee that a variable can always stay in a register and will never be spilled (how would the compiler do that for functions calls?), it'd have to essentially treat all variables as potentially-modified by basically any store-via-pointer, which would essentially disable all optimizations.</p>
]]></description><pubDate>Fri, 25 Apr 2025 20:13:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=43798071</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=43798071</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43798071</guid></item><item><title><![CDATA[New comment by dgrunwald in "C stdlib isn't threadsafe and even safe Rust didn't save us"]]></title><description><![CDATA[
<p>The problem with `setenv` is that people expect one process to have one set of environment variables, which is shared across multiple languages running in that process. This implies every language must let its environment variables be managed by a central language-independent library -- and on POSIX systems, that's libc.
So if libc refuses to provide thread-safety, that impacts not just C, but all possible languages (except for those that cannot call into C-libraries; as those don't need to bother synchronizing the environment with libc).</p>
]]></description><pubDate>Wed, 22 Jan 2025 20:38:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=42797226</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=42797226</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42797226</guid></item><item><title><![CDATA[New comment by dgrunwald in "C stdlib isn't threadsafe and even safe Rust didn't save us"]]></title><description><![CDATA[
<p>How exactly would that help in this situation?<p>If both Rust and C have independent standard libraries loaded into the same process, each would have an independent set of environment variables. So setting a variable from Rust wouldn't make it visible to the C code, which would break the article's usecase of configuring OpenSSL.<p>The only real solution is to have the operating system provide a thread-safe way of managing environment variables. Windows does so; but in Linux that's the job of libc, which refuses to provide thread-safety.</p>
]]></description><pubDate>Wed, 22 Jan 2025 20:31:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=42797162</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=42797162</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42797162</guid></item><item><title><![CDATA[New comment by dgrunwald in "Rust: Investigating an Out of Memory Error"]]></title><description><![CDATA[
<p>Yes, that is typically the way to go.<p>Collecting a call stack only requires unwinding information (which is usually already present for C++ exceptions / Rust panics), not full debug symbols. This gives you a list of instruction pointers. (on Linux, the glibc `backtrace` function can help with this)<p>Print those instruction pointers in a relative form (e.g. "my_binary+0x1234") so that the output is independent of ASLR.<p>The above is all that needs to happen on the production/customer machines, so you don't need to ship debug symbols -- you can ship `strip`ped binaries.<p>On your own infrastructure, keep the original un-stripped binaries around. We use a script involving elfutil's eu-addr2line with those original binaries to turn the module+relative_address stack trace into a readable symbolized stack trace.
I wasn't aware of llvm-symbolizer yet, seems like that can do the same job as eu-addr2line.
(There's also binutil's addr2line but in my experience that didn't work as well as eu-addr2line)</p>
]]></description><pubDate>Sun, 19 Jan 2025 16:51:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=42758703</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=42758703</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42758703</guid></item><item><title><![CDATA[New comment by dgrunwald in "C++ String Conversion: Exploring std:from_chars in C++17 to C++26"]]></title><description><![CDATA[
<p>Caution with these functions: in most cases you need to check not only the error code, but also the `ptr` in the result.
Otherwise you end up with `to_int("0x1234") == 0` instead of the expected `std::nullopt`, because these functions return success if they matched a number at the beginning of the string.</p>
]]></description><pubDate>Mon, 14 Oct 2024 07:14:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=41835024</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=41835024</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41835024</guid></item><item><title><![CDATA[New comment by dgrunwald in "C++'s `noexcept` can sometimes help or hurt performance"]]></title><description><![CDATA[
<p>> All noexcept does is catch any exception and immediately std::terminate.<p>While that's a possible implementation; the standard is a bit more relaxed: `noexcept` may also call `std::terminate` immediately when an exception is thrown, without calling destructors in the usual way a catch block would do.<p><a href="https://godbolt.org/z/YTe84M5vq" rel="nofollow">https://godbolt.org/z/YTe84M5vq</a>
test1 has a ~S() destructor call if maybe_throw() throws; test2 never calls ~S().<p>MSVC does not appear to support this optimization, so using `noexcept` with MSVC involves overhead similar to the catch-block.</p>
]]></description><pubDate>Mon, 05 Aug 2024 19:27:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=41164561</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=41164561</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41164561</guid></item><item><title><![CDATA[New comment by dgrunwald in "I Hope Rust Does Not Oxidize Everything"]]></title><description><![CDATA[
<p>The GC does matter.<p>Most applications are completely fine with having a garbage collector, but they are not fine with having multiple garbage collectors!
Mixing multiple garbage collected languages is a recipe for complex bugs. At a minimum, reference cycles across the languages will result in memory leaks.<p>Thus every garbage collected language tends to grow its own ecosystem of libraries, with the whole world having to be re-implemented in that language.
The only exception are the C/C++/Rust libraries, as these can be used (through C FFI interface) by almost every other language. This is precisely because these languages do not introduce their own heavy-weight runtime (especially: no GC), allowing them to be combined with another language's runtime.<p>Thus widely used libraries must be written in one of the non-GC languages, even if 100% of the applications using them are fine with having a garage collector.</p>
]]></description><pubDate>Tue, 16 Jul 2024 15:12:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=40977336</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=40977336</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=40977336</guid></item><item><title><![CDATA[New comment by dgrunwald in "CVE-2024-6409: OpenSSH: Possible remote code execution in privsep child"]]></title><description><![CDATA[
<p>There are some static analysis tools that can check this.<p>Cert's SIG30 rule page has a list: <a href="https://wiki.sei.cmu.edu/confluence/display/c/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers" rel="nofollow">https://wiki.sei.cmu.edu/confluence/display/c/SIG30-C.+Call+...</a><p>Also there's <a href="https://clang.llvm.org/extra/clang-tidy/checks/bugprone/signal-handler.html" rel="nofollow">https://clang.llvm.org/extra/clang-tidy/checks/bugprone/sign...</a></p>
]]></description><pubDate>Tue, 09 Jul 2024 16:24:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=40917941</link><dc:creator>dgrunwald</dc:creator><comments>https://news.ycombinator.com/item?id=40917941</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=40917941</guid></item></channel></rss>