Giving C a superpower: custom header file (safe_c.h)
111–120 of 277 posts
Re: Giving C a superpower: custom header file (safe_c.h)
#112Earlier quoted context omitted.
> very exotic requirements I'd be interested to know what you are thinking. The primary exotic thing I can imagine is an architecture lacking the ability to do atomic operations. But even in that case, C11 has atomic operations [1] built in. So worst case, the C library for the target architecture would likely boil down to mutex operations. [1] https://en.cppreference.com/w/c/atomic.html
Which platforms might that be? Even MIPS has atomics (at least pointer sized last i checked).
// Not real MIPS, just what I've gleaned from a brief look at some docs
LOAD addr, register
ADD 1, register
STORE register, addr
The LOAD and STORE are atomic, but the `ADD` happens out of band.That's a problem if any sort of interrupt happens (if you are multi-threading then a possibility). If it happens at the load, then a separate thread can update "addr" which mean the later STORE will stomp on what's there.
x86 and ARM can do
ADD 1, addr
as well as other instructions like "compare and swap" LOAD addr, register
MOV register, register2
ADD 1, register2
COMPARE_AND_SWAP addr, register, register2
if (cas_failed) { try again }Re: Giving C a superpower: custom header file (safe_c.h)
#113Earlier quoted context omitted.
Why would I want to run a garbage collector and deal with it's performance penalties?
IDK about Fil-C, but in Java garbage collector actually speeds up memory management compared to C++ if you measure the throughput. The cost of this is increased worst-case latency. A CLI tool (which most POSIX tools are) would pick throughput over latency any time.
But you're never going to encounter a C++ program that does that, since it makes no sense.
Re: Giving C a superpower: custom header file (safe_c.h)
#114Any hopes that MSVC will add C23 support before 2040?
Re: Giving C a superpower: custom header file (safe_c.h)
#115Intentionally or not, this post demonstrates one of the things that makes safer abstractions in C less desirable: the shared pointer implementation uses a POSIX mutex, which means it’s (1) not cross platform, and (2) pays the mutex overhead even in provably single-threaded contexts. In other words, it’s not a zero-cost abstraction. C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and…
It's an implementation detail. They could have used atomic load/store (since c11) to implement the increment/decrement.
TBH I'm not sure what a mutex buys you in this situation (reference counting)
Re: Giving C a superpower: custom header file (safe_c.h)
#116Nice, but if the intention is portability my experience has unfortunately been that you pretty much have to stick to C99. MSVC’s C compiler is rough, but pretty much necessary for actual cross platform. I have my own such header which has many, many things like the OP’s. As much as I would find it constantly useful, I don’t have a cleanup utility because of this. But if you can stay out of MSVC world, awesome! You ca…
You can use GCC on MS Windows just fine. Installing MSYS2 will also give you a package manager.
Re: Giving C a superpower: custom header file (safe_c.h)
#117Intentionally or not, this post demonstrates one of the things that makes safer abstractions in C less desirable: the shared pointer implementation uses a POSIX mutex, which means it’s (1) not cross platform, and (2) pays the mutex overhead even in provably single-threaded contexts. In other words, it’s not a zero-cost abstraction. C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and…
The number of times I might want to write something in C and have it less likely to crash absolutely dwarfs the number of times I care about that code being cross-platform. Sure, cross-platform is desirable, if there's no cost involved, and mandatory if you actually need it, but it's a "nice to have" most of the time, not a "needs this". As for mutex overheads, yep, that's annoying, but really, how annoying ? Modern…
For this use-case, you might not notice. ISTR, when examing the pthreads source code for some platform, that mutexes only do a context switch as a fallback, if the lock cannot be acquired.
So, for most use-cases of this header, you should not see any performance impact. You'll see some bloat, to be sure.
Re: Giving C a superpower: custom header file (safe_c.h)
#118Earlier quoted context omitted.
Well, basically, yeah, if your platform lacks support for atomics, or if you'd need some extra functionality around the shared pointer like e.g. logging the shared pointer refcounts while enforcing consistent ordering of logs (which can be useful if you're unfortunate enough to have to debug a race condition where you need to pay attention to refcounts, assuming the extra mutex won't make your heisenbug disappear), o…
Does there exist any platform which has multithreading but not atomics? Such a platform would be quite impractical as you can't really implement locks or any other threading primitive without atomics.
You can't create userspace locks which is a bummer, but the OS has the capability of enforcing locks. That's basically how early locking worked.
The main thing needed to make a correct lock is interrupt protection. Something every OS has.
To go fast, you need atomic operations. It especially becomes important if you are dealing with multiple cores. However, for a single core system atomics aren't needed for the OS to create locks.
Re: Giving C a superpower: custom header file (safe_c.h)
#119Earlier quoted context omitted.
Yes, plenty have been done already so since Lisp Machines, Smalltalk, Interlisp-D, Cedar, Oberon, Sing#, Modula-2+, Modula-3, D, Swift,.... It is a matter to have an open mindset. Eventually system languages with manual memory management will be done history in agentic driven OSes.
Swift, by design, does not have GC.
Re: Giving C a superpower: custom header file (safe_c.h)
#120Earlier quoted context omitted.
I consider code written in Frama-C as a verifiable C dialect, like SPARK is to Ada, rather than C proper. I find it funny how standard C is an undefined-behaviour minefield with few redeeming qualities, but it gets some of the best formal verification tools around.
The popular C compilers include a static analyzer and a runtime sanitizer. What features do you consider proper C? The C standard has always been about standardization of existing compilers, not about prescribing features.
While these are a huge improvement over no extra tooling, they don't compare to analyzers like Frama-C plugins, which demand further annotations/proofs if necessary to show code is free of UB, and you can provide further to show your code is not just safe, but correct. Assuming one doesn't ship rejected code, the latter is pretty much its own language with much stronger guarantees, much like SPARK is to Ada.
I like sanitizers and other compiler-specific guarantees, they at least try to fill the gaps by giving proper semantics to UB. But the ones available for C are still insufficient, and some are very resource-heavy compared to just running safe code. I'm excited about Fil-C showing a path forward here.