News for hackers. Stuff that matters.

david2ndaccount

You write it down and if you don’t remember you just make up something plausible.
Re:Much Ado About None: Sentinel Values in Python on Saturday October 31, 2026 @11:23PM (#50322438)
The answer is they don't in practical code but they come up in generic code, where you want to wrap something that is already returning an optional in your optional. In languages that do support optional[optional[whatever]], if you every actually write that you know you've messed up your API.
Re:Iterating Backwards in C on Friday October 30, 2026 @02:51AM (#50300590)
I was unclear in the article, but in my defense I wrote it in a hurry on the couch after seeing the convoluted backwards loop an llm had extruded. I meant if you are actually doing something with the index variable other than indexing. Mixing signed and unsigned types, possibly of different sizes, has surprising behavior to many programmers who don’t have the “usual arithmetic conversions” memorized. If you’re working in size_t the result simplifies: everything becomes size_t. And you generally have size_t anyway as you’re using the result of sizeof or an allocation size passed to your allocation function.

In general I want to avoid signed types for counts and sizes as then you have to consider both boundary conditions which is easy to mess up.

Re:The October inflection point for vibe game development on Wednesday October 28, 2026 @04:29PM (#50280445)
Counter point: a buddy of mine who doesn’t know how to program has been vibe-coding a video game for the last month. He got very excited early on with what he thought was quick progress, but it’s been a month and he still doesn’t have anything approaching a game or even what he wants.
Re:Show HN: Qwen3-4B with the AI writing tics trained out on Monday October 19, 2026 @01:40PM (#50155400)
There’s no contradiction. Consider this thought experiment: the real range of possible outcomes is a number from 1-100, but your model is a six-sided die so it produces a number from 1-6. It is random, unpredictable and non-deterministic and yet you will get “samey” results compared to the real range of possible outcomes.
Re:Fun Extending the C Preprocessor on Monday October 19, 2026 @03:41AM (#50149498)
Right, you can work around it with things like this, but it means you’re forcing the C compiler to parse a compound literal just to get its length, 5 times! when the preprocessor already knows the length of `__VA_ARGS__`. Such contortions when you want a little bit of info that the compiler already has are what cause your compiler times to blow up if you try to do anything sophisticated with the cpp.

Your version expands `sum(1, 2, 3, 4, 5, 6)` to:

    sum(sizeof ((int []){0, 1, 2, 3, 4, 5, 6}) / sizeof *((int []){0, 1, 2, 3, 4, 5, 6}) - 1, ((int []){0, 1, 2, 3, 4, 5, 6}) + (sizeof ((int []){0, 1, 2, 3, 4, 5, 6}) / sizeof *((int []){0, 1, 2, 3, 4, 5, 6}) > 1))
whereas with __VA_COUNT__ it is just:

    sum(6, (int[]){1, 2, 3, 4, 5, 6})
Re:Fun Extending the C Preprocessor on Monday October 19, 2026 @03:32AM (#50149450)
__map() expands its arguments, like other function-like macros.
Re:Fun Extending the C Preprocessor on Sunday October 18, 2026 @07:27PM (#50146549)
We’ll get there in this series.
Re:Fun Extending the C Preprocessor on Sunday October 18, 2026 @06:21PM (#50146089)
> If the compiler supports "-E", there absolutely is some 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.

Whitespace is significant in the preprocessor so of course it tracks whitespace. Whitespace isn’t dropped until phase 7 when pp-tokens are converted to C tokens.

As I said it’s not impossible, write the patch and see if GCC accepts it.

Re:Fun Extending the C Preprocessor on Sunday October 18, 2026 @05:01PM (#50145447)
During translation of source text to a C program, the source text goes through several phases. It turns raw bytes into preprocessor tokens, then preprocessor tokens get expanded into more preprocessor tokens and then preprocessor tokens get translated into C tokens, which are fed into the C parser. There is no “expanded text”, only expanded tokens. Generally this is implemented as a state machine that produces tokens on demand, so there is no expanded text. When GCC shows you that error message, it uses the recorded source location and looks it up in the original source file. This is trivial to do. Expanding just one line of the source file would either require re-invoking the preprocessor from the beginning or storing already consumed preprocessor tokens.

Obviously this is possible, but no one has gotten around to implementing this feature and it’s not clear you would want either solution: buffering preprocessor tokens in case you need to expand a line for an error message greatly increases memory usage and the vast majority of compilations are successful ones with no errors, slowing down the normal case. And re-invoking the preprocessor to show you one line on every error message makes error reporting slow.

Re:Fun Extending the C Preprocessor on Saturday October 17, 2026 @10:44AM (#50131630)
The article shows how to implement map, but it should be a builtin
"In the face of ambiguity, refuse the temptation to guess."
Re:Type Safe Generic Data Structures in C on Monday October 05, 2026 @03:02PM (#49969005)
Their specification is pretty bad, allowing code like:

    #include <stdio.h>
    #include <stddef.h>
    void v(int y[printf("hello world!\n")]){ 
    }

    int main(){
        v(NULL);
        typedef int wut[printf("oh no\n")];
    }
    $ cc vla.c && ./a.out
    hello world!
    oh no
`typedef`s with side effects...
Re:Type Safe Generic Data Structures in C on Monday October 05, 2026 @01:46PM (#49968010)
I agree. Alas I have a day job and my other hobby is going for long hikes. But when the days get shorter and the weather is worse I’ll write some more!
Re:Type Safe Generic Data Structures in C on Monday October 05, 2026 @11:42AM (#49966343)
Hey that’s me! Cool to see people like my stuff.
Re:Social Reality in China on Friday October 02, 2026 @04:43PM (#49938382)
Weird to talk about these traits like Chinese cynicism and generational trauma without even mentioning the Great Leap Forward and Cultural Revolution.
Re:C's Flexible Integer Sizes Were Not a Design Mistake on Sunday September 27, 2026 @06:15PM (#49871381)
I’m sorry but this is just incorrect. When you take the address of a thread local variable you have to lookup its real address using something like __tls_get_addr or by reading its offset via fs/gs but once it’s in a pointer it’s just a regular absolute address and is fine to dereference on any thread. There is no separate type for a pointer to a thread local variable.
Re:C's Flexible Integer Sizes Were Not a Design Mistake on Sunday September 27, 2026 @05:23PM (#49871000)
I don’t know what you mean, if you take the address of a thread local variable you get a regular pointer which is just as safe to dereference as any other pointer, cast through intprt_t or not?
Re:C's Flexible Integer Sizes Were Not a Design Mistake on Sunday September 27, 2026 @03:25PM (#49869968)
`thread_local` is a storage class, there is no `thread_local T*` in the same way there is no `static T*`
Re:C extensions, portability, and alternative compilers on Tuesday May 26, 2026 @02:05AM (#48275621)
Use the new standards-conformant preprocessor with `/Zc:preprocessor`

https://learn.microsoft.com/en-us/cpp/build/reference/zc-pre...

Pascal strings might be the only string design worse than C strings. C Strings at least let you take a zero copy substring of the tail. Pascal strings require a copy for any substring! Strings should be two machine words - length + pointer (aka what is commonly called a string view). This is no different than any other array view. Strings are not a special case.
Re:TSMC to make advanced AI semiconductors in Japan on Monday February 09, 2026 @12:19AM (#46941835)
The world won’t allow a dependence on a single geopolitically threatened entity in the long run, so either they defuse that risk themselves or risk a competitor filling that role. This move is better for TSMC itself.
Re:C/C++ Embedded Files on Friday December 26, 2025 @01:18PM (#46394632)
If you want to remain portable, write your code in the intersection of the big 3 - GCC, Clang and MSVC - and you’ll be good enough. Other implementations will either be weird enough that many things you’d expect to work won’t or are forced to copy what those 3 do anyway.
Re:C/C++ Embedded Files on Friday December 26, 2025 @01:16PM (#46394608)
You can apply `#` to __VA_ARGS__, which won’t preserve the exact whitespace, but for many languages it’s good enough. biggest issue is you can’t have `#` in the text.
Re:How to write type-safe generics in C on Saturday November 15, 2025 @10:07AM (#45937922)
I wrote a similar article in the past: https://www.davidpriver.com/ctemplates.html

I use this technique in my hobby projects as it has worked out the best for me of the options I’ve explored.

Re:Recursive macros in C, demystified (once the ugly crying stops) on Wednesday November 05, 2025 @10:56PM (#45831248)
Works with MSVC if you add /Zc:preprocessor (to get a standard compliant preprocessor instead of the legacy one).
Re:Writing memory efficient C structs on Wednesday July 30, 2025 @12:13PM (#44736118)
The author relies on the compiler fitting the bitfield in unused padding bytes after “speed”, but that is implementation-defined behavior (almost everything about bitfields is implementation defined). MSVC will align the unsigned bitfield to alignof(unsigned), whereas GCC and clang will use the padding bytes. To portably pack the struct, use unsigned integers and use flags (monster.flags & CAN_FLY instead of monster.can_fly).

See https://c.godbolt.org/z/K7oY77KGj

Older »