Live data from Hacker News

Git's list of banned C functions

github.com

201–210 of 639 posts

Re: Git's list of banned C functions

#201

Earlier quoted context omitted.

This is a lot like how in JavaScript you have footguns like the with statement or in Python 2 where you have Unicode issues, etc. I am sure we could definitely a new C standard that excludes these functions as obsolete, but the linked header file is a pretty sensible interim solution. C is an old language and it’s kind of amazing that code written 30 years ago can still by and large be compiled by a modern compiler.…

It amuses me that HN hates JS so much, that even a topic about problems with C turns into a JS-bashing thread. Also, I just want to remind you that JS isn't just React. There are plenty of libraries written in C that introduce breaking changes over the course of 3 years. Nothing will stop people from finding ways to complain about JS though, I know. The hate-boner is very real.

I appreciate Javascript's LISPy qualities, but it has an inordinate number of footguns and a relative lack of standard, stable libraries. Coming from languages like Java and Erlang that are relatively scrupulous about such things is a bit jarring.

I do like Typescript though, as it adds some really nice ergonomics.

Re: Git's list of banned C functions

#202

Earlier quoted context omitted.

Why are these functions deprecated in favor of others but not removed? I know in Javascript this can happen so as to not break older websites, but in a compiled language this shouldn't be a problem right?

The expectation of a C89 programmer is that a valid C89 program can be compiled for any machine that has a C89 compiler, and likewise for C95, C99, C11, and C17. Furthermore, it's expected that any C89 program can be compiled unchanged on any future version of C, and the standard library is part of the definition of the language, and therefore functions cannot be removed.

At a certain point we have to say that it’s wrong for someone to expect C89 should still be the LCD.

And yes: it should all still compile, but none of that prohibits the compiler from issuing flashing red/yellow warning messages to your terminal for using footgun functions, preferably with uncomfortable audible notifications too.

All of this is silly though, because even in a strict C89 environment you can still have your own safe wrappers over the unsafe functions. I find that very little of modern programming has a hard dependency on ultramodern compiler features (e.g. you can theoretically build React/Redux using only ES3 (1998ish) if you like. Generics using type-erasure can be implemented with macros. Etc.).

Also, C89 conformance doesn’t mean much: you can have a confirming C89 system that doesn’t even have a heap - nor a stack for autos! (IBM Z/series uses a linked-list for call-frames, crazy stuff!)

Re: Git's list of banned C functions

#203

Earlier quoted context omitted.

The commits actually do give that info. Take for instance this commit: https://github.com/git/git/commit/c8af66ab8ad7cd78557f0f9f5e... It actually gives examples and a lengthy explanation and reasoning behind the ban.

Now that's what a good commit message looks like!

Commit messages like that are common in the Linux kernel project, which is where git came from (though this particular commit message is a bit on the longer side).

It makes more sense if you think of it as an email message justifying why the project maintainer should accept that change, because that's what they were before git even existed. Still today, unless you're one of the Linux kernel subsystem maintainers, you have to convert your changes to emails with git-format-patch/git-send-email and send them to the right mailing list. Even the Linux kernel subsystem maintainers keep writing commits in that style out of habit (and because Linus will rant at them if they don't).

Re: Git's list of banned C functions

#204
post #125

Earlier quoted context omitted.

I find it highly backwards that documentation on "what to use instead of X" is in the commit message disabling X. One _might_ do it and might remember to do it, but IMO it makes absolutely no sense for this not to be documented properly in code, as suggested by OP. By that logic, a non-insignificant amount of (good) comments in code could be removed and people asked to "git blame the code and check out the commit tha…

I disagree. Commits messages exist for the very purpose of adding context to your code base. If you added for something that needs context, sure MAYBE add a comment, but I really pray that I'm going to find a few paragraphs disambiguating the problem within a git commit. If I'm _really_ lucky, maybe I find a PR number or Jira ticket reference as well. If you're truly clueless as to what could be substituted for these…

So, you are tied to Git for eternity to preserve documentation?

Might work in practice for a long time, but Git is a version control system, not a documentation system.

Re: Git's list of banned C functions

#205

Its really wild, as a person coming from other languages who has written maybe ten lines of C in his life that the functions that seem to be massive footguns in C are, like, "format a string" or "get time in GMT." That's... really scary.

If you list the languages you use, I'd be happy to point out the "footguns" in each of them. For all the warts on C, there really is no language that can compete for what it has accomplished over ~50 years. Recall that during the rise of C, people were writing machine code on punch cards. Assembly -> Machine code has far more footbullets than C, it is a tradeoff between hand holding and tiny fast code. Wow, this blew…

Your edit really isn't helping your case.

Those of us who have always known about less dangerous 'system' languages (Pascal probably being the most popular) lament the fact that so much code got written in C instead.

It wasn't inevitable. It was preventable! It just didn't happen that way for reasons which are largely historical.

I don't work for the Rust Evangelism Strike Force, my main project is written in (as little) C (as possible), but I beg anyone who has a choice: use something else! Rust is... fine, Zig is promising. Ada still works!

Writing out the set {Python, Pascal, Algol, Rust, Go} tempts me to say uncharitable things about your understanding of the profession, but I accept you were just being snarky so I'll just gesture in the direction of how $redacted that is.

Re: Git's list of banned C functions

#206

Its really wild, as a person coming from other languages who has written maybe ten lines of C in his life that the functions that seem to be massive footguns in C are, like, "format a string" or "get time in GMT." That's... really scary.

Yeah, because of NUL-terminated strings. They cause so many problems it's not even funny. Even something simple like computing the length of the string is a linear time operation that risks overflowing the buffer. People attempted to fix these problems by creating variations of those functions with added length parameters, thereby negating nearly all benefits of NUL-terminated strings.

Why can't we just have some nice structures instead?

  struct memory {
      size_t size;
      unsigned char *address;
  };

  enum text_encoding { TEXT_ENCODING_UTF8, /* ... */ };

  struct text {
      enum text_encoding encoding;
      struct memory bytes;
  };
All I/O functions should use structures like these. This alone would probably prevent an incredible amount of problems. Every high-level language implements strings like this under the hood. Only reason C can't do it is the enormous amount of legacy code already in existence...

Re: Git's list of banned C functions

#208

Its really wild, as a person coming from other languages who has written maybe ten lines of C in his life that the functions that seem to be massive footguns in C are, like, "format a string" or "get time in GMT." That's... really scary.

The decision to make C strings null terminated with implied length instead of length + blob continues to trip us up, 30+ years later. There's a good reason the "safe" versions of those functions all take length parameters. But way back when this approach was chosen, I don't think the state of the art could fully predict this outcome. But also, "strings" and "time" are actually very complex concepts, and these functio…

The reason that the safe functions take length parameters is that they produce a new object in uninitialized memory, a pointer to which is specified by the caller.

It has nothing to do with null termination.

And that uninitialized memory is not self-describing in any way in the C language. Which is that way in machine language also.

This is a problem you have to bootstrap yourself somehow if you are to have any higher level language.

The machine just gives you a way to carve out blocks of memory that don't know their own type or size. C doesn't improve on that, but it is not the root cause of the situation. Without C, you still have to somehow go from that chaos to order.

Copying two null terminated strings into an existing null-terminated string can be perfectly safe without any size parameters.

   void replace_str(char *dest_str, const char *src_left, const char *src_right);
If dest_str is a string of 17 characters, we know we have 18 bytes in which to catenate src_left and src_right.

This is not very useful though.

Now what might be a bit more useful would be if dest_str had two sizes: the length of string currently stored in it, and the size of the underlying storage. This particular operation would ignore the former, and use the latter. It could replace a string of three characters with a 27 character one.

Re: Git's list of banned C functions

#209

Earlier quoted context omitted.

Many of C's problems relate to string handling. These are all legacy functions which have been replaced with safe alternatives many decades ago. strcpy() was replaced with a safer strncpy() and in turn has been replaced with strlcpy(). The list is a ban of the less safe versions, where more modern alternatives exist.

Why are these functions deprecated in favor of others but not removed? I know in Javascript this can happen so as to not break older websites, but in a compiled language this shouldn't be a problem right?

It's not great if you're working on a new release and you realize you also need to change something unrelated because the language changed under you, especially if it's just a bugfix but a high-priority one, or consider the head-aches caused by source-only distributions suddenly breaking for all your new users (or existing users switching to a new computer or spinning up a fresh VM).

Re: Git's list of banned C functions

#210

Earlier quoted context omitted.

It’s funny, I worked exclusively with MISRA at the start of my career. Eventually I started a job at a FAANG and received quizzical comments on why I implemented a memory arena. The argument was to allocate memory freely and let it pool memory as necessary. Fair enough, it was simpler and fit the standard expectation of development. The issue is that if you talk with the allocator team they complain of not being able…

The lack of runtime allocations in game engine programming comes from a different motivation: allocations are expensive, garbage collections are expensive, cache coherency matters, and you're chucking around a lot of very similar looking objects, so... object pools!

Yeah, the first time we coded a scroller shooting game with my friend (at school), we were baffled that our terminal-based scroller lagged more than the raycaster we did two weeks prior. Was it a C vs C++ thing?

Turns out, creating then destroying every single missile/enemy was extremely costly

Post reply on HN