<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: Joker_vD</title><link>https://news.ycombinator.com/user?id=Joker_vD</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 19 Oct 2026 10:17:42 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=Joker_vD" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by Joker_vD in "A 'Ludicrously Ugly' Bridge Is Exhibit a That Britain Has Lost Its Mojo"]]></title><description><![CDATA[
<p>A regular remainder that brutalism, despite what many people think, was originally invented in the UK.</p>
]]></description><pubDate>Mon, 19 Oct 2026 00:29:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=50146961</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50146961</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50146961</guid></item><item><title><![CDATA[New comment by Joker_vD in "16-bit fully functional DIY magnetic core memory"]]></title><description><![CDATA[
<p>It <i>is</i> the future, and has been the future for almost 40 years already! I bet that's what the hoverboards will use inside their microcontrollers — gotta drive those portable fusion reactors reliably!</p>
]]></description><pubDate>Sun, 18 Oct 2026 23:17:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=50146488</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50146488</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50146488</guid></item><item><title><![CDATA[New comment by Joker_vD in "Namecheap just seized and disabled all my domains"]]></title><description><![CDATA[
<p>Next thing, you're going to argue that when the US sanctioned the whole population of Crimea back in 2014, that also was "a poorly thought-out virtue-signalling knee-jerk" reaction that worsened, for no good reason, the situation of the helpless Ukrainians who had happened to live there and now also had to live under Russia's brutal rule <i>and</i> face the international isolation. But you'd be wrong.</p>
]]></description><pubDate>Sun, 18 Oct 2026 21:50:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=50145835</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50145835</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50145835</guid></item><item><title><![CDATA[New comment by Joker_vD in "Namecheap just seized and disabled all my domains"]]></title><description><![CDATA[
<p>Hey, it's not enough that your own government oppresses you — you better get some additional oppression from the overseas, just to make sure you know they have your best interests at their heart, honest-honest.</p>
]]></description><pubDate>Sun, 18 Oct 2026 21:45:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=50145803</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50145803</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50145803</guid></item><item><title><![CDATA[New comment by Joker_vD in "Fun Extending the C Preprocessor"]]></title><description><![CDATA[
<p>> There is no “expanded text”, only expanded tokens.<p>If the compiler supports "-E", there absolutely is <i>some</i> equivalent of the expanded text, with (somewhat limited) whitespace info available: if you insert whitespace into between "b" and the comma in "b,", then "-E" invocation will dutifully show it. Yes, multiple spaces are collapsed into one, but their presence/absence is tracked already.<p>> Expanding just one line of the source file would either require re-invoking the preprocessor from the beginning or storing already consumed preprocessor tokens.<p>Yeah, keep the whole expansion of the latest top-level (not nested) macro. I believe some bytecode-like compression scheme (a replay of that state machine you mentioned) à la LZ would work fairly well, with minor additional memory necessary. Hell, scratch that: since #define/#undef are impossible inside a macro, you don't even need to remember the expansion of the macro, you simply  need to keep the current macro definitions and remember what was the last macro you tried to expand — if your error happened inside its expansion, just re-expand again. Zero additional memory needed, since this information is already stored for the current way of error reporting — you can see in the current output that it remembers what macros it expanded and where, the whole path down to the offending token: at 1:21 "in expansion of macro 'W'" which was at 2:18 "in expansion of macro 'X'" which was at 5:13.<p>> And re-invoking the preprocessor to show you one line on every error message makes error reporting slow.<p>Eh, it's on the whole faster than making the programmer re-run with "-E" option manually.</p>
]]></description><pubDate>Sun, 18 Oct 2026 21:38:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=50145735</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50145735</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50145735</guid></item><item><title><![CDATA[New comment by Joker_vD in "Fun Extending the C Preprocessor"]]></title><description><![CDATA[
<p>> I can directly inspect the result of the preprocessor makes macros easier to debug<p>Tangential note but: why does this require a separate re-invocation of the compiler with the '-E' flag? Say I have this silly example with a comma instead of the semicolon inside W() macro:<p><pre><code>    #define W(a, b)  b, int a
    #define X(a, b)  W(b, a)

    int kekw(int x) {
        int z = X(23, k) = x;
        return z + k;
    }
</code></pre>
When I shove it into GCC without -E, it says<p><pre><code>    <source>: In function 'int kekw(int)':
    <source>:1:21: error: expected unqualified-id before 'int'
        1 | #define W(a, b)  b, int a
          |                     ^~~
    <source>:2:18: note: in expansion of macro 'W'
        2 | #define X(a, b)  W(b, a)
          |                  ^
    <source>:5:13: note: in expansion of macro 'X'
        5 |     int z = X(23, k) = x;
          |             ^
    <source>:6:16: error: 'k' was not declared in this scope
        6 |     return z + k;
          |       
</code></pre>
instead of, you know, showing me the expanded text so that I could see what's actually wrong with the generated variable declarations? Something like<p><pre><code>    <source>: In function 'int kekw(int)':
    <source>:1:21: error: expected unqualified-id before 'int'
        1 | #define W(a, b)  b, int a
          |                     ^~~
    <source>:2:18: note: in expansion of macro 'W'
        2 | #define X(a, b)  W(b, a)
          |                  ^
    <source>:5:13: note: in expansion of macro 'X'
        5 |     int z = X(23, k) = x;
          |             ^
    <source>:5:-: note: the expanded source text is
          |     int z = 23, int k = x;
          |                 ^~~
    <source>:6:16: error: 'k' was not declared in this scope
        6 |     return z + k;
          |       
</code></pre>
perhaps? I understand that tracking the lines/columns inside the expanded text is highly non-trivial (although collapsing them all onto the position of the top-level macro is already just as non-trivial), but still. Show me what the source that you actually can't compile, not the three-steps removed precursor to it — I sure as hell can't expand macros in my head.<p>Also, what is this first error message about in the first place? Why the hell does it expect unqualified-id <i>before</i> "int"? If you put "int" <i>after</i> the unqualified-id, it still would be illegal; and an unqualified-id is not the only thing that can follow the comma in this context anyway.</p>
]]></description><pubDate>Sun, 18 Oct 2026 20:36:01 +0000</pubDate><link>https://news.ycombinator.com/item?id=50145233</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50145233</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50145233</guid></item><item><title><![CDATA[New comment by Joker_vD in "Teal – A statically-typed dialect of Lua"]]></title><description><![CDATA[
<p>How many statically-typed dialects of Lua are there anyway? I know there is Terra. There was also... Sol, I think? Anything else?</p>
]]></description><pubDate>Sun, 18 Oct 2026 19:11:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=50144260</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50144260</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50144260</guid></item><item><title><![CDATA[New comment by Joker_vD in "Superoptimizing an FPU Emulator"]]></title><description><![CDATA[
<p>Ah, the silly tradeoffs the ISAs expose us to. The CTZ/CLZ is fundamentally faster than floating point subtraction; but that doesn't mean that the CLZ/CTZ instruction will be faster than the FSUB. It <i>could</i> be but the vendors may as well decide to make it as slow as (or even slower than) FSUB.</p>
]]></description><pubDate>Sun, 18 Oct 2026 11:29:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140081</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50140081</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140081</guid></item><item><title><![CDATA[New comment by Joker_vD in "The plight of the public potty"]]></title><description><![CDATA[
<p>> public bathroom are a disgracefully neglected human right.<p>Well, they are. Just as drinking fountains.<p>> Public restrooms don't come from Santa Claus, and they cost a lot both to build and maintain. Then there are the costs and miseries of security. Gratitude toward business providing restrooms seems nonexistent.<p>s/restroom/park/g. Hey, it's still true! And explains why there are almost no public parks around.<p>Edit: oh, and before someone comments on unhygienicity of drinking fountains: you're not supposed to kiss the nozzle or, heavens forbid, to fellate it to drink. Let about 1/2–1/3 of the top of the spout inside of your mouth and drink it; leave the rest outside.</p>
]]></description><pubDate>Sun, 18 Oct 2026 09:35:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=50139467</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50139467</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50139467</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>It may <i>seem</i> like an exceedingly bad thing, but in practice most shift amounts are constants, statically known to the compiler, which makes choosing between single instruction-long sequences "shl eax/rax, <imm8>", "shr eax/rax, <imm8>", and "xor eax, eax" trivial.<p>But variable shifts also happen sometimes, which brings me to the next point:<p>> in exchange for UB in cases that never occur in practice.<p>It does happen, and people depend on what their platform does. That's one of the things that sunk John Regehr's proposal for "Friendly C" [0]:<p><pre><code>    After publishing the Friendly C Proposal, I spent some time discussing its design with people,
    and eventually I came to the depressing conclusion that there’s no way to get a group of C
    experts — even if they are knowledgable, intelligent, and otherwise reasonable — to agree on
    the Friendly C dialect. There are just too many variations, each with its own set of performance
    tradeoffs, for consensus to be possible. [...] Another example is what should be done when a
    32-bit integer is shifted by 32 places (this is undefined behavior in C and C++). Stephen Canon
    pointed out on twitter that there are many programs typically compiled for ARM that would fail
    if this produced something besides 0, and there are also many programs typically compiled for
    x86 that would fail when this evaluates to something other than the original value. So what is
    the friendly thing to do here?
</code></pre>
So. You want a modulo behaviour? Write "expr << (var & 32)" or "expr << (var & 64)", the compiler will recognize this idiom and emit a simple "mov cl, var; shl eax/rax, cl" on x64 and RISC-V, and an additional explicit AND mask on ARMs. You want an overshift? Well, that's the default semantics, and it would emit an simple shift on ARM, and "xor eax, eax; shl edx/rdx, cl; cmp ecx, 32/64; cmovb eax/rax, edx/rdx" on x64 (and something similar on RISC-V). It's your choice!<p>[0] <a href="https://blog.regehr.org/archives/1287" rel="nofollow">https://blog.regehr.org/archives/1287</a></p>
]]></description><pubDate>Sat, 17 Oct 2026 13:02:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=50130786</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50130786</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50130786</guid></item><item><title><![CDATA[New comment by Joker_vD in "C, Type Systems, GLib, and API Design"]]></title><description><![CDATA[
<p>The language kinda forces one to use void pointers, as the path of the least resistance. I've seen your implementation of type-safe containers and it's a <i>lot</i> more effort (and requires rather recent version of C) than simply having a pointer-to-void as the payload.<p>Although GLib indeed has some rather weird design/taste.<p>> and why is it called gpointer?<p><pre><code>    An untyped pointer, exactly equivalent to void*.

    The standard C void* type should usually be preferred in new code, but gpointer
    can be used in contexts where a type name must be a single word, such as in the
    GType name of G_TYPE_POINTER or when generating a family of function names for
    multiple types using macros.
</code></pre>
Hey, they <i>do</i> have type-generating facilities! They just don't use them to template their containers. It's a very, very old library, it predates C99.</p>
]]></description><pubDate>Sat, 17 Oct 2026 12:37:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=50130576</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50130576</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50130576</guid></item><item><title><![CDATA[New comment by Joker_vD in "C++26: The New Debugging Header"]]></title><description><![CDATA[
<p>...there is no bloody way debuggers don't just subtract 1 from the EIP on INT 3. Like... there is no way. Right?</p>
]]></description><pubDate>Fri, 16 Oct 2026 22:40:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=50125745</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50125745</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50125745</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>Ah, I see. Those "final drafts PDFs" are a bit confusing to google, I must admit. I guess I'd better save them once locally, properly titled, and reference those copies instead?<p>In any case, thanks; it's nice to see C++ at least fully embracing the mandate on integers being two's complement, <i>finally</i>. There is enough footguns already without basic arithmetic operators being UB half of the time.</p>
]]></description><pubDate>Fri, 16 Oct 2026 12:29:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=50117562</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50117562</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50117562</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>Apparently, C++23 went on and fully defined it, see the sibling comment from leni536 [0]:<p><pre><code>    1) ........................ The behavior is undefined if the right operand is negative,
    or greater than or equal to the width of the promoted left operand.

    2) The value of E1 << E2 is the unique value congruent to E1 × 2**E2 modulo 2**N, where
    N is the width of the type of the result.

    [Note 1 : E1 is left-shifted E2 bit positions; vacated bits are zero-filled. — end note]

    3) The value of E1 >> E2 is E1 / 2**E2, rounded down.

    [Note 2 : E1 is right-shifted E2 bit positions. Right-shift on signed integral types is
    an arithmetic right shift, which performs sign-extension. — end note]
</code></pre>
So you can adopt that as well. In any case: since C23/C++23 the integers are two's complement, so make them behave so. Again, I don't mind signed overflow being undefined all that much (although again, I feel like there has to be some middle ground between "full-blown UB and nasal demons" and "the implementations/sanitiziers are allowed to trap it instead of silently wrapping/assuming it never happens") so perhaps you can slightly deviate from C++ here: it apparently allows 1 << (INT_WIDTH - 1) to become INT_MIN, fully defined-ly, maybe this can still be UB in C? But (-1) << (whatever up to INT_WIDTH - 1) absolutely should be defined, it's just ridiculous otherwise.<p>[0] <a href="https://news.ycombinator.com/item?id=50117296">https://news.ycombinator.com/item?id=50117296</a></p>
]]></description><pubDate>Fri, 16 Oct 2026 12:20:09 +0000</pubDate><link>https://news.ycombinator.com/item?id=50117483</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50117483</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50117483</guid></item><item><title><![CDATA[New comment by Joker_vD in "C++26 Contracts: Introduction to Preconditions and Postconditions"]]></title><description><![CDATA[
<p>FTFY: "Most bugs happen in the space of things that the programmer thinks can't happen but happen anyways". I'm sure we all have stories about some baffling error that simply couldn't have occurred, it's impossible, and then you spent an hour staring at the code, reading the tracing logs, and then finally finding a single-character typo responsible for it. Whoops, it's not supposed to be "if (p != nil) { return false; }", it's meant to be "if (p == nil) { return false; }"!<p>But yeah, that's precisely what contracts are (at least originally) intended to be, but you can quite clearly see from this comment section that this is <i>not</i> how they're going to be used. Well, this surely gonna be "fun" experience down the line for the C++ programmers...</p>
]]></description><pubDate>Fri, 16 Oct 2026 09:58:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=50116402</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50116402</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50116402</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>No, not really? From C++23:<p><pre><code>    4) The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits
    are filled with zeros. If E1 has an unsigned type, the value of the result
    is E1 × 2**E2, wrapped around. If E1 has a signed type and nonnegative value,
    and E1 × 2**E2 is representable in the result type, then that is the resulting
    value; otherwise, the behavior is undefined.

    5) The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an
    unsigned type or if E1 has a signed type and a nonnegative value, the value of
    the result is the integral part of the quotient of E1 / 2**E2. If E1 has a
    signed type and a negative value, the resulting value is implementation-defined.
</code></pre>
It's marginally more well-defined, sure, but not fully. The right shifts of negative numbers are no longer UB but are still an unportable mystery; and the left shifts of negative values are still outright UB.</p>
]]></description><pubDate>Thu, 15 Oct 2026 20:57:21 +0000</pubDate><link>https://news.ycombinator.com/item?id=50110105</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50110105</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50110105</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>Some ancient machines trapped on signed overflow, including the ones caused by arithmetic shift left (as opposed to logical shift left), and apparently you can't define your implementation-defined behaviour as "oh, it traps in this case" — although still I don't believe the last part.<p>But if it <i>is</i> true, then yeah, that'd make (some) sense. I say "some" because surely in this case the implementations could simply emit the "logical shift left" instruction for the shift operation both for ints and unsigned ints? I don't think there ever was a machine that actually tracked the signedness/unsignedness of registers.</p>
]]></description><pubDate>Thu, 15 Oct 2026 20:50:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=50110014</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50110014</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50110014</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p><p><pre><code>    4   Conformance

    A strictly conforming program shall use only those features of the language and
    library specified in this document.

    [...]

    The two forms of conforming implementation are hosted and freestanding. A
    conforming hosted implementation shall accept any strictly conforming program.
</code></pre>
And it doesn't say anywhere in the standard that it's optional to support FENV_ACCESS pragma — it's a feature in the standard, so if you want to be a conforming implementation, you have to implement it. Of course, you can always be a non-conforming implementation, that also is allowed. Who's to stop you?</p>
]]></description><pubDate>Thu, 15 Oct 2026 08:51:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=50101018</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50101018</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50101018</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>> And one of those kinds of "blast radius" is traps,<p>Wait. An implementation-defined behaviour isn't allowed to be trap/termination of execution? Okay, make it unspecified then, with the options of trapping or calculating some unspecified (not indeterminate) integer value.<p>> N3863<p>Hm?<p><pre><code>    Because implementation-defined behavior relies on the definition of unspecified behavior, it
    means that implementation-defined behavior requires two or more possibilities to be defined in
    the standard. However, a brief look at its uses in the standard clearly shows that there isn’t
    always a list of potential behaviors to pick from.
</code></pre>
Eh, I'd argue that omission of such a list is merely an implicit infinite ("two or more", you know) list of possibilities, its construction being self-evident.<p><pre><code>    N3783 5.2.1.2p1.1: Physical source file multibyte characters are mapped, in an implementation-
    defined manner, to the source character set (introducing new-line characters for end-of-line
    indicators) if necessary.
</code></pre>
There is an infinite list of possible ways to map multibyte characters to the source character set — an implementation has to pick one and document it.<p><pre><code>    N3783 5.2.1.3p1: A conforming implementation shall produce at least one diagnostic message
    (identified in an implementation-defined manner)
</code></pre>
There is an infinite list of possible diagnostic messages...<p><pre><code>    N3783 5.2.2.2p1-2: In a freestanding environment (in which C program execution can take
    place without any benefit of an operating system), the name and type of the function called at
    program startup are implementation-defined.
</code></pre>
There is an infinite list of possible C identifiers that an implementation may chose as the name of the function to call at program startup.</p>
]]></description><pubDate>Thu, 15 Oct 2026 06:13:14 +0000</pubDate><link>https://news.ycombinator.com/item?id=50099871</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50099871</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50099871</guid></item><item><title><![CDATA[New comment by Joker_vD in "Your C is not standard C"]]></title><description><![CDATA[
<p>> I was thinking about eliminating this shift-into-left bit UB.<p>At least make it "<i>change</i> of the sign bit is UB" — if 0 shifts into the sign-bit of a positive number, or 1 shifts into the sign-bit of a negative number, that shouldn't be UB. This would make left-shifts of negative numbers well-defined, their behaviour being that of two's complement numbers. And C23 already demands two's complement from the implementations, doesn't?<p>> signed overflow UB can be turned into traps using sanitizers.<p>Well, yeah, sure, but shifting -1 one place to the left doesn't overflow, it produces -2; only shifting INT_MIN or something up to and including INT_MIN + (INT_MAX/2) would overflow.</p>
]]></description><pubDate>Thu, 15 Oct 2026 05:57:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=50099759</link><dc:creator>Joker_vD</dc:creator><comments>https://news.ycombinator.com/item?id=50099759</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50099759</guid></item></channel></rss>