Live data from Hacker News

Some C habits I employ for the modern day

unix.dog

31–40 of 162 posts

Re: Some C habits I employ for the modern day

#31

> I’ve long been employing the length+data string struct. If there was one thing I could go back and time to change about the C language, it would be removal of the null-terminated string. It's not necessary to go back in time. I proposed a way to do it in modern C - no existing code would break: https://www.digitalmars.com/articles/C-biggest-mistake.html It's simple, and easy to implement.

> the fatal error was not combining the array dimension with the array pointer; all it needs is a little new syntax a[...]; this won’t fix any existing code. Over time, the syntax a[] can be deprecated by convention and by compilers. You're thinking in decades. C standard committee is slower than that. This could have worked in practice, but probably never will happen in practice. Maybe people should start considerin…

The C committee is not afraid to add new syntax. And this is an easy addition.

Not only does it deliver a massive safety improvement, it dramatically speeds up strlen, strcmp, strcpy, strcat, etc. And you can pick out a substring without needing to allocate/copy. It's easy money.

Re: Some C habits I employ for the modern day

#32

> and I end up having all these typedefs in my projects I avoid doing this now. It's more trouble than it's worth and it changes your code from a standard dialect of C into a custom one. Plus my eyes are old and they don't enjoy separating short identifiers. > typedef struct { ... } String I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling. C23 finally gave us "auto", you sh…

> > typedef struct { ... } String

> I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling.

Well then imagine if Gtk made you write `struct GtkLabel`, etc. and you saw hundreds of `struct` on the screen taking up space in heavy UI code. Sometimes abstractions are worthwhile.

Re: Some C habits I employ for the modern day

#33
Please don’t buy into “no const”. If you’ve ever worked with a lot of C/C++ code, you really appreciate proper const usage and it’s very obvious if a prototype is written incorrectly because now any callers will have errors. No serious reusable library would expose functions taking char* without proper const usage. You would never be able to pass a C++ string c_str() to such a C function without a const_cast if that were the case. Casting away const is and should be an immediate smell.

Re: Some C habits I employ for the modern day

#34

Earlier quoted context omitted.

There is some irony in someone replying to the author of the D language suggesting that maybe the D language is the real solution he's looking for.

It might be the language he is looking for, but it might not, and more likely than not is not. D is one of those odd languages which most likely ought to have gotten a lot more popular than it did, but for one reason or another, never quite caught on. Perhaps one reason is because it lacks a sense of eccentricity and novelty that other languages in its weight class have. Or perhaps it's just too unfamiliar in all the…

D is an elegant re-imagine of C and C++. For a trivial example,

    typedef struct S { int a; } S;
becomes simply:

    struct S { int a; }
and unlike C:

    extern int foo();
    int bar() { return foo(); }
    int foo() { return 6; }
you have:

    int bar() { return foo(); }
    int foo() { return 6; }
For more complex things:

    #include 
becomes:

    import foo;

Re: Some C habits I employ for the modern day

#35

> I’ve long been employing the length+data string struct. If there was one thing I could go back and time to change about the C language, it would be removal of the null-terminated string. It's not necessary to go back in time. I proposed a way to do it in modern C - no existing code would break: https://www.digitalmars.com/articles/C-biggest-mistake.html It's simple, and easy to implement.

https://web.archive.org/web/20260116161616/https://www.digit... for anyone here while we're swamping Walter's site

The site is built out of static pages, so it takes a lot to swamp it!

Re: Some C habits I employ for the modern day

#37

> and I end up having all these typedefs in my projects I avoid doing this now. It's more trouble than it's worth and it changes your code from a standard dialect of C into a custom one. Plus my eyes are old and they don't enjoy separating short identifiers. > typedef struct { ... } String I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling. C23 finally gave us "auto", you sh…

> > typedef struct { ... } String > I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling. Well then imagine if Gtk made you write `struct GtkLabel`, etc. and you saw hundreds of `struct` on the screen taking up space in heavy UI code. Sometimes abstractions are worthwhile.

The main thing I dislike about typedefs is that you can't forward declare them.

If I know for sure I'm never going to need to do that then OK.

Re: Some C habits I employ for the modern day

#38

Earlier quoted context omitted.

There is some irony in someone replying to the author of the D language suggesting that maybe the D language is the real solution he's looking for.

It might be the language he is looking for, but it might not, and more likely than not is not. D is one of those odd languages which most likely ought to have gotten a lot more popular than it did, but for one reason or another, never quite caught on. Perhaps one reason is because it lacks a sense of eccentricity and novelty that other languages in its weight class have. Or perhaps it's just too unfamiliar in all the…

[dead]

Re: Some C habits I employ for the modern day

#39
post #6

Regarding memory, I recently changed to try to not use dynamic memory, or if I need to, to do it once at startup. Often static memory on startup is sufficient. Instead use the stack much more and have a limit on how much data the program can handle fixed on startup. It adds the need to think what happens if your system runs out of memory. Like OP said, it's not a solution for all types of programs. But it makes for v…

This.

As someone who spent most of their career as an embedded dev, yes, this is fine for (like parent said) some types of software.

Even for places where you'd think this is a bad idea, it's still can be a good approach, for example allocating and mapping all memory up to the limit you are designing. Honestly this is how engineering is done - you have specified limits in the design, and you work explicitly to those limits.

So "allocate everything at startup" need not be "allocate everything at program startup", it can be "allocate everything at workflow startup", where "workflow" can be a thread, a long-running input-directed sequence of functions, etc.

For example, I am starting a tiny stripped down web-server for a project, and my approach is going to be a single 4Kb[1] block for each request, allocated via a pool (which can expand on pressure up to some maximum) and returned to the pool once the response is sent.

The 4Kb includes at most 14 headers (regardless of each headers size) with the remaining data for the JSON payload. The JSON payload is limited to at most 10 fields. This makes parsing everything "allocate-less" because the array holding pointers to the keys+values of the header is `const char *headers[14]` and to the payload JSON data `const char *fields[10]`.

A request that doesn't fit in any of that will be rejected. This means that everything is simple and the allocation for each request happens once at startup (pool creation) even while parsing the input.

I'm toying with the idea of doing the same for responses too, instead of writing it out as and when the output is determined during the servicing of the request.

-------------------------

[1] I might switch to 6Kb or 8Kb if requests need more; whatever number is chosen, it's going to be a static number.

Re: Some C habits I employ for the modern day

#40

> I think one of the most eye-opening blog posts I read when getting into programming initially was the evergreen parse, don’t validate post Bro, that was written in 2019. If it's not old enough to drink it's not yet evergreen. But it's also long-winded. A 25-minute read, and y'know what the conclusion is? "Parsing leaves you with a new data structure matching a type, validation checks if some data technically compli…

> You don't need a programming language to natively support types in order to implement the concept yourself in that language.

In a programming language that doesn't enforce types, how do you implement

> "Parsing leaves you with a new data structure matching a type, validation checks if some data technically complies with a type (but might not later be parsed correctly)".

Post reply on HN