Kernel drivers and embedded system bare metal firmware.
The problem with C is that in any bigger project something always slips through even the best programmers, reviewers, static analysis and unit tests. And that something can lead to disastrous crashes and security vulnerabilities.
Of course you can shoot yourself into foot with stuff like metatables in Lua and Python metaclasses and whatnot. Then again you should see some C macro messes around...
Anyways I don't like when people defend C with that age old argument it requires a clever disciplined programmer that never makes mistakes. Because either such programmers don't exist or they're very rare.
Fewer defects, or just different (arguably less severe) defects? It's great that you're sure, but evidence would be even better.
Scripting languages do have their pitfalls. Lua and python can have type mismatches and even typos causing misbehavior, things that usually aren't issues with C.
However, you do need significantly less code than in C.
C and C++ = Logic Errors + Memory Corruption + UB
From this point of view,
Σ Logic Errors < Σ (Logic Errors + Memory Corruption + UB)
That said, sometimes I'm shocked what kind of disasters get past the analyzers.
Stakes are higher than ever. It's not just about functional correctness and avoiding crashes anymore. Your code needs to be secure against outside world malicious actions. Getting rid of counterintuitive security vulnerabilities is very, very hard.
Sadly we are a very very tiny percentage, as proven by Herb Sutter question to the audience at CppCon (1% of the audience answered positively), and CVE frequent updates.
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=memory+corr...
Just imagine how many millions the IT industry and PhD research have spent developing solutions that would improve C's safety, many of them largely ignored by most C developers.
You can still overwrite memory but it suddenly became much less likely.
Yeah, bare metal systems often don't allocate at all. Although one sin they often do commit is using same buffer for multiple purposes. What could go wrong...
Perhaps even more common is allocating a buffer on stack and writing past bounds somehow. Also DMA to/from stack is usually not a great idea...
Above things sound dumb, but can easily happen when you build your abstraction layers and use them carelessly.
wait what oh my god
That's also true of all the other languages.
Good C-compilers will most of the time take care of the superscalar CPU friendliness. When they don't, you can always drop down to the assembler level, and it'll mesh well with C.
Likewise most static languages defer to the compiler for CPU-specific performance optimisations and will permit foreign native calls into C or ASM where necessary. So I don't see how this is an argument in C's favour.
You often also need correct alignment. Cache-line or page. Your unboxed access across two pages can cause two TLB misses, L1 misses etc. Not to mention two page faults.
Sometimes you need to ensure two (or more) buffers are NOT aligned in a particular way to avoid interfering with CPU caching mechanisms.
Something like this for example:
char* aligned_buf;
char* buf;
size_t max_align_offset = (1<<align) - 1;
buf = malloc(length_needed + max_align_offset);
aligned_buf = (buf + max_align_offset) & ~max_align_offset;
In the example, if align==8, you have 256 byte alignment. If it's 12, 4kB alignment.It was just an example to show one way how C can control alignment.
#include <stdlib.h>
void *aligned_alloc(size_t alignment, size_t size);
which works like malloc() but lets you specify the required alignment.C wins them all in implicit conversions and opportunities for memory corruption.
Their major sin was to be tied to commercial OSes, instead of one with source code available for a symbolic price to universities.
This doesn't actually refute the assertion that C is dangerous :)
Control and increased safety are not mutually exclusive. I'll take safe-by-default, unsafe-when-asked any day. It's not 1972 anymore.
C is a very useful language and one you basically have to know if you're interested in low level software but it's very, very far from flawless.
If you look at many high profile software vulnerabilities of late (heartbleed, goto fail, etc...) many can be traced to the lack of safety and/or bad ergonomics of the C language.
We need to grow up as an industry and accept that using a seatbelt doesn't mean that you're a bad driver. Shit happens.