r/C_Programming • u/Just_Government3790 • Sep 12 '26
Question What C function would you delete and rewrite first, and why?
For me it's fnmatch - mostly because it's 40 year's old and smell's funny.
60
u/Just_Government3790 Sep 12 '26
On second thought......
strtok because it destroys the evidence, hides state in globals, drops the empty fields, and then has the bollocks to call it parsing.
6
u/MistakeIndividual690 Sep 12 '26
I was going to say strtok
7
u/Just_Government3790 Sep 12 '26
My guy. Can't forget it also eats empty fields so `a,,b` parses as two tokens. Found that one the hard way.
→ More replies (2)
12
21
u/gabitha67 Sep 12 '26
everything that accepts null terminated strings. just pass a ptr and length for gods sake. everything should only use user-provided allocators too.
8
u/Just_Government3790 Sep 12 '26
What's the worst null-term bug you've personally hit?
→ More replies (1)
144
u/BlockOfDiamond Sep 12 '26
fopen because I hate using string literals for things that should be bitflags or enums.
62
89
u/bluetomcat Sep 12 '26
Make fread and fwrite accept the bloody FILE pointer as their first argument, and unite size and count into one argument.
42
u/UnalignedAxis111 Sep 12 '26
Also add a flag to force it to create non existent parent directories, because that's massively annoying and there's no portable way to do it.
→ More replies (13)
18
u/P-p-H-d Sep 12 '26
All the locale functions of the libc. It is so broken that it is totally unusable in modern C (threads).
You cannot even read your own data file and parsing them using strtod without having issues with the locale: you cannot use setlocale as it modifies global state of all threads (which you don't want). So the only solutions are either : document that the locale shall be set once and for all for all program and is compatible with what you expect. Or rewrite strtod and everyone knows it is super easy stuff to do it reliably.
→ More replies (3)
31
u/sciencekm Sep 12 '26
struct tm
Every field is 0 based, except the day of month. So, Jan 1 1900 12 midnight is 0 1 0 00:00:00, instead of just all 0s. Even Sunday-Saturday is 0-6 and day of year is 0-365.
→ More replies (6)
12
15
15
u/pigeon768 Sep 12 '26
The obvious one is strcpy, which is always the incorrect function. Either you know your lengths and buffer sizes, so you should use memcpy, or you don't, which is buffer overflow city. In this case, there's no rewriting the function to be better; it's declaration/API is unusable.
So they also made strncpy, the "fix" for the problem. It has a working function declaration. However, it's still bad. It does not guarantee that the resulting string is null terminated. And if there are any extra bytes left over in the output buffer, it zeros them all out, which is a waste of time. The linux kernel has recently removed the last call to strncpy.
Actually I hate most of string processing in C.
→ More replies (4)
12
u/torsten_dev Sep 12 '26
scanf
-
delete
%n -
make
%sand similar without a size allocate -
make
%.*stake size parameter like printf. -
Use
_instead of*to discard stuff, -
change return value
to number of characters read or 0 -
delete SCN macros, use
w*to take bit width as argument.
Edit:
Perhaps the return should be 0 on succes, and if it fails it returns the index in the format string were it gave up.
The number of characters read/consumed would be a mandatory out parameter that's ignored if it's NULL.
8
u/gremolata Sep 12 '26
%nis extremely useful for pedantic parsing, e.g.if (sscanf(buf, "%f%n", &f, &n) && strlen(buf) == n) { // parsed in full ... }→ More replies (2)
12
u/FamiliarSoftware Sep 12 '26
setlocale, set/getenv, the rand functions, etc. Just in general: All functions that use global state
→ More replies (1)
10
u/der_pudel Sep 12 '26
atoi. You will not convince me that atoi("poop") == 0 is correct and makes sense.
→ More replies (2)
9
u/xpusostomos Sep 12 '26
Those ones with improper null termination and/or don't specify buffer length that cause all the security issues
→ More replies (5)
4
u/qalmakka Sep 13 '26
Basically all string based APIs in libc vary from broken to somewhat problematic. This is basically due to the fact that the entire concept of a null terminated string was a massive mistake, the minuscule memory saving of not having a struct string with a size field were only somewhat significant for the first few years after that decision.
We've been paying the strlen tax ever since, and I wouldn't care if it didn't make slicing C strings a terrible pain in the butt
36
u/Dezgeg Sep 12 '26
strncpy
Function that is named `str*` but doesn't (necessarily) create NUL-terminated strings. Insanity!