What are some good tools to make C programming more memory safe? Maybe not to the level of rust but closer. Especially looking for any libraries to write safer code.
What are some good tools to make C programming more memory safe? Maybe not to the level of rust but closer. Especially looking for any libraries to write safer code.
how do i learn c
learnxinyminutes. com/docs/c/
>how do i learn c
https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-langs.md#go
Static analyzers
Can you name some?
https://clang.llvm.org/docs/AddressSanitizer.html
That's dynamic, not static
Sure
https://en.m.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
Which ones do you use?
I sometimes use valgrind to double check but I just code with memory management in mind when I use languages like C
valgrind
based, but valgrind is a filter for windowsgays
hmm maybe a garbage collector? it's a bit of overhead though.
MISRA C
The fact there are people who unironically think that MISRA C is a tool that makes C safer speaks volumes to how moronic this board has gotten.
safe enough for aviation software, safe enough for me
allocate all memory on program startup, simple as
One of NASA's requirements for deep space probe software.
basically what all safety critical embedded things I've worked on do
Pretty easy to make checks for dynamic memory however to ensure you aren't going out of bounds, or that you have a memory leak by simply substituting your malloc/realloc/free calls with debug functions that count everything, and additionally over-allocate to ensure you aren't overrunning. Anything not caught by that is a logic error that you've missed in your tests and leads to bad state anyways, so not the fault of dynamic memory
>additionally over-allocate to ensure you aren't overrunning
What a moronic idea
why? you only do it when running in debug mode and can verify integrity of whatever you wrote to that additional space to check for overruns
Anon, it has merit in *some* cases, e.g.:
There is a loop in the program where each iteration thereof will require a newly allocated block of memory.
Not only is it a good idea to handle the allocation before the loop, it will also lead to faster running code as doing one big allocation leads to less overhead than many small ones.
Plus, you get one (contiguous) block of memory to deal with as opposed to many smaller ones.
>less UB
Then you're also getting less performance.
This is what soidev morons don't get, most of the speed of C and assembly is in optimization specifically enabled by UB.
C originally was supposed to be merely "portable assembly", but over time was steered into the direction of exploiting UB.
This is specifically why compiler implementers are very much always conservative when it comes to pushing changes in the C standard.
It doesn't work on windows? What a shit OS.
>Then you're also getting less performance.
>"if it doesn't have to produce correct results I can make it trivially fast"
Rust/Zig can be fast because results are strongly defined; the steps to get those results aren't.
>>"if it doesn't have to produce correct results I can make it trivially fast"
oh but it does produce correct results, and better ones than in Rust
>and better ones than in Rust
[Citation needed]
post github and dilate cs50 kiddy
Zig still has UB. Just better designed UB. You can exploit a lot of UB in zig in order to be extremely fast, you're just less likely to do it by accident than C.
>You can exploit a lot of UB in zig in order to be extremely fast
Do you have examples?
The unreachable expression is a big one. Similar to __builtin_unreachable, but actually part of the language.
Overflow is UB by default on signed *and* unsigned integers; all overflow kinds are UB normally, which includes shifts/mul/div/etc.
Many built-ins like floatToInt assert that the arguments are correct.
Every step of the way are assertions that the correct things are going on. When you build with safety disabled, these asserts become UB.
>optimization specifically enabled by UB
this is not true for modern compilers. modern compilers optimize the IR, not the code or the ast. two languages using the same compiler backend (llvm, for example) and producing the same IR will, in turn, produce the same output. the people that think "the compiler will optimize it" usually don't know how the compiler works
but your point is wrong even without considering that. if you need some parts of the language to behave differently depending on the architecture, you can specify that. a good "portable assembly" should have a predictable output when unoptimized and a predictable behavior when optimized
>>less UB
>Then you're also getting less performance.
>This is what soidev morons don't get, most of the speed of C and assembly is in optimization specifically enabled by UB.
It's not strictly UB that makes optimizations possible, it's generically "stuff that should never happen". UB is one example, but conditions that can be verified to never occur by a static type system or other analyses are just as effective without making the language as much of a minefield.
For example, Rust's mutable references are always able to be implemented with the equivalent of C's restrict pointers and the optimizations that come with them. It's also interesting to note that, in unsafe Rust, there is no strict aliasing. It's not UB to write one field of a union and then read another, or read an integer variable as a float variable by casting a pointer to it. These are disallowed in C because of the optimization opportunities, but they're allowed in Rust because unsafe code is such a small part of any given program that it's not really a big deal to allow them. You get the equivalent of C's strict aliasing in safe code, instead, thanks to the use of enums instead of unions and references instead of pointers.
Don't use variables.
Follow classic fortran variable naming conventions.
Your brain.
Zig. Less UB. Better error handling. Better pointers. Better arrays. Slices. Keep run-time safety on and it will catch most problems. Use the GPA to detect improper allocations & leaks.
-fsanitize=address is the simplest and most effective thing you can do.
Just putting it out there in case you are not using it for some reason.
Looking through this guys websites, can't tell if he's a genius or a moronic autist
I had to close it out of frustration. Why does he think he knows better where I want to scroll than I do?
rustc
A brain for starters
/therad
Store handles, not pointers
https://floooh.github.io/2018/06/17/handles-vs-pointers.html
Please have a nice day unironically
>Doesn't know about libasan
>Doesn't know about valgrind
>Doesn't know about MISRA C
>Doesn't know about compiler hardening
>Doesn't understand tradeoffs between optimization and access boundaries/security
>Doesn't know about proof checkers and static analysis
This is why we got r*st in the first place, ignorance.
How can people still be so ignorant with all the knowledge of humanity at their fingertips? It really baffles the mind.
asan, ubsan, libfuzzer, valgrind
it is possible to do object-oriented programming on c you can find this out on YouTube.
it's possible to build a framework that is accessible by a methods and those methods are all memory safe.
Common sense and having a brain. You don't need the language and the compiler to hold your hand for you if you're not the most abject fricking moron there is.
D
Valgrind + address sanitizer
>memory safe? What is that?
I only use C with the hashtag.
>make C programming more memory safe
using C++
hmm, sounds pretty cool to learn actually. i often hear people say "the compiler will optimize it", if it turns out that's bullshit that is kind of game changing. would you learn more about this in like a compilers course or something?
https://functionalcs.github.io/curriculum/#Compilers
is really easy to follow, watch one class per day, complete the exercises and after a month you will know more about compilers than 95% of this board
Really nice link, cheers
Type safety and smart pointers aka C++
UB affects the IR. You can specify in the LLVM IR whether you want overflow to poison in any given arithmetic operation, and whether pointers can be assumed to not alias. Rust's unreachable_unchecked() is insta-UB purely for the sake of optimization, it outputs a corresponding IR instruction.
I'm not a compiler expert though, so maybe you're right in spirit in some way that's going over my head.