~ C, Ada, Rust and the safety of languages ~

by kalekale on 2023-12-31
on why you should think twice before writing your next project in C and consider something else

$ cat userwelcome.c
/*
A simple program to demonstrate how unsafe C is if you are a careless programmer,
This is just an example and I dont expect anyone to make mistakes like this. 
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct machine {
        char username[12];
        char password[12];
};

int main() {
        struct machine *home = malloc(sizeof(struct machine));

        scanf("%s", home->username);

        /* assume this program is part of PID 1, which is started as a root process 
           and assume the password was opened from a root-only file /etc/passwd
           and from there we strcpy the password into home->password */
        strcpy(home->password, "1337"); 

        printf("hello %s\n", home->username);
}

$ gcc userwelcome.c  -Wall -pedantic -std=c11 -Werror -O3
$ ./a.out
kalekalethegreatest
hello kalekaletheg1337

$ cat notes.txt
These small silly mistakes have caused many a CVE, and it is mostly due the shotgun 
that the compiler gives to the programmer. Every programmer, smart or not, should 
consider using a safer language for their usecase, is what I believe. 

The following program demonstrates a buffer overflow. Anyone who knows how to program in C can tell you what exactly is wrong in this program, and will also defend the C programming language shifting the blame on the programmer. The C language is about as close as you can get to machine while also enjoying the high level programming syntax. I would aruge this ability to shoot yourself on the foot is a feature of the C language. Programming in C can be very fun but it should very much be limited to what it does the best, machine level programming. Using a language like C for high level purpose is a bad idea for one single reason and that being userspace level programmer really do not understand how the program is being operated at the lower level and nor they should. It should not be the duty of a game developer to bother himself with the nuances of low level programming.

So am I going to shill rust? not really. But yes, I would love to see Rust replace C as it really does solve alot of the problems. The difficulty curve is also good! it keeps away potentally stupid programmers from making low quality programs. However in case of rust stupid programmers are already making low quality grabage due to the hype around the language. But I assume slowly the hype will fade away and rust will find its place in systems and performance critical spaces only.

I will not be shilling rust, but instead of it I will be shilling some better alternatives for userland programs, which are fast, secure and easy to program in. These languages are some of the most fun and easy languages I have ever used, but I never see people talk about it.

Nim and Go are relatively new and really dont have much to offer, Go is like C but safe and slow, Nim is like a mix of Python and Ada which runs about as fast as C, as the language itself is a transpiler to C.
Ada stands out among these as Ada was designed to be safe and fast. The syntax is pretty easy as comfy. It can also be easily used alongside C or any thing that follows the C ABI. I want to see more people try this language instead of dickriding the Rust hype, even 30 years ago people knew C was not a safe and reliable language, which is why the USA's DOD came up with this language.

so how can you claim Ada is safe but C is not? and why not Rust??

To determine if a language is safe or not, we must first know what a safe language is, this is my attempt at a defination of a safe language.
A safe programming language can be defined as language which discourages the programmer to write programs with memory related bugs and has minimum undefined behaviours.

now, let me demonstrate which languages are safe, and which are not based on this defination.

Assembly/Machine code:
The machine code is just the instruction that is fed to a CPU, the assembler's task is to only convert the given instructions into byte code, this implies it has no mechanism to discourage programmer from writing memory related bugs because, as long as the syntax is ok the program should assemble.

C/C++:
The C programming language does have safety nets to stop programmers from writing memory related bugs but it has a major loopholes, mainly due the all the undefined behaviours. The compiler also gives all the power to the programmer and allows the programmer to do whatever he wants. In the given C program eariler we could see how I was allowed to copy a 19 character long string on a string which was only supposed to store 12, which ended up overwriting the '/0' byte at the end of the string and would leak the data later stored on the address after the 12th byte. And if you noticed there is also a memeory leak! because I forgot to free the malloc'ed struct!! This shows my incompetence as a programmer but also shows the language does not have efforts to stop me from being incompetent. This alone makes C as a very unsafe language.
I am not a C++ programmer and I am aware of smart pointers so I assume its alot safer than plain old C, no comments other than that.

Java/Python:
Java is a run on VM and has garbage collectors, so that alone solves the problem of safety. However, based on my experience Java program still leak alot of memory. Python may not run on a VM but the interpreter is in principle very similar to a VM and the language is garbage collected so other than the minor leaks there isnt a major problem. These languages are safe, but whats the point if they cant even be used where safety matters the most (ie. machines, kernels, algorithms and cryptography).

Rust:
Rust easily passes the safety test but it should be noted that while working at the machine level it is impossible to work without the unsafe{} blocks. The borrow checker is a very interesting concept, if a programmer understands this theory, he will never write memory related bugs on the userland level, safety at the kernel/machine level is still debatable but it is still alot alot alot better than going raw C. In the end it does depend on the level of the programmer. Rust is the ideal language for writing alot of high level programs, like browsers, cryptography, video games for sure and generally just any high level program that needs to be super fast. At the kernel level and machine level I still crown C as the king because its simple and unsafe, Rust at the machine level is complex and unsafe. Simple as.

NOTE: when i refer to safety, I mean in terms of high level programs, low level programs by nature cannot be safe, unless we're talking about Ada..

Ada:
Ada was designed by the DoD as a safe language to program the metal, however I do not care about programming the metal, lets talk about how safe Ada is on the userland level, it first needs to be known that unlike C which the bell labs guys planned for it to be a general purpose language, Ada was developed as the ideal systems programming language. But keeping the metal aside, I want to put forth the claim that Ada is a better language to write fast general purpose userland programs, of course I am ignoring the ecosystem and talking purely based on what the language is. Ada has an excellent type system, this is a death blow against Rust because I, as a programmer wont have to deal with the nuaneces of borrowing by using the stack, and Ada with SPARK also has borrow mechanics, not as advanced as Rust but its good enough for most use cases at the high level. Ada also has a different approach to program, unlike the usual C style its very structured, imperative and object oriented. It is STRONGLY TYPED, and I say this in all caps because their motto is literally, "In strong typing we trust".
The following is a demonstration of how you would define your types in the language.
type Day_type   is range    1 ..   31;
type Month_type is range    1 ..   12;
type Year_type  is range 1800 .. 2100;
type Hours is mod 24;
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

type Date is
   record
     Day   : Day_type;
     Month : Month_type;
     Year  : Year_type;
   end record;
Ada also has mechanism to stop you from making retarded operations like Subtracting a Month_type from a Day_type, Which C WOULD LET YOU DO, because in the end its all just bytes right?? Wrong! letting the programmer make these retarded instructions is the same as a temple priest letting the local biker gang host their party on the temple shrine.
And also for context, the C program cannot be recreated in Ada meaning the compiler will stop you from making memory related errors with all the checks. This makes Ada a very safe language. SPARK also does not allow any UBs as far as I know so that makes a very strong case for Ada, considering its easier to pick up than Rust.
Ada, like Rust demonstrates how far we as programmers and enginners have come, but the problem is Ada gets 0 attention while Rust gets all of it. Rust and Ada are a product of years of research by multiple masters of programming, enginnering and mathematics. There have been many languages developed by students and researchers to cook the perfect safe language, Rust and Ada takes many of the ideas from those research papers.
So what was the point of this article? Try Ada, its fun, its worth it, and you might land a job at the DoD or NASA if youre a US citizen.

But its still not stopping me from writing my hobby projects like system k and manu init in C, because I love C and I expect no one else to use my programs, especially not on critical systems. But, if the goverment assigned me to write a program for their space mission I would pick Ada no doubt, and at the same time if I was given lots of money and told to design a web brower or a game engine, I would hire Rust programmers. One thing is for sure, if I was a serious pro programmer or an enginner I would not be using C. Even in research labs, Ada should be used over C, I WOULD not want to leak memory on the machine thats programming a nuclear reactor. But hey im just a hobby programmer, we hobby programmers are known to make terrible programs, like the cancer treatment machine's program, which was made by a hobby programmer on his PDP-11 and never had a test run (killed 6 people iirc). STAY SAFE AND REMEMEBR TO FREE YOUR MALLOCS! AND HAPPY NEW YEARS!!