You have to look back, to move ahead. Lets look back and take a look at C, C++ and how the language feels, then move on to more modern languages. Lets get going!
GCC
GCC is the Gnu Compiler for compiling C programming language. C is a general purpose imperative programming language with a static type system. Sounds great doesn’t it! Lets create Hello World.
#include <stdio.h>
int
main (void)
{
printf("Hello, world!n");
return 0;
}
On a Mac, you don’t have to install anything, The C compiler is already available so you can just type the following.
$ gcc -Wall hello.c -o hello
$ ./hello
Hello, world!
# determine file type
$ file hello
hello: Mach-O 64-bit executable x86_64
# determine file size
$ ls -alh hello
-rwxr-xr-x 1 dennis staff 8.2K Nov 28 18:05 hello
Unsafe operations
Lets try something unsafe! Lets create an array with 5 elements, and lets access the 6th element. What will happen?
#include <stdio.h>
int
main (void)
{
int arr[] = {1,2,3,4,5};
printf("arr [0] is %dn", arr[0]);
printf("arr [1] is %dn", arr[1]);
printf("arr [2] is %dn", arr[2]);
printf("arr [3] is %dn", arr[3]);
printf("arr [4] is %dn", arr[4]);
// surprise!!
printf("arr [5] is %dn", arr[5]);
return 0;
}
Outputs:
$ gcc -Wall unsafe.c -o unsafe
$ ./unsafe
arr [0] is 1
arr [1] is 2
arr [2] is 3
arr [3] is 4
arr [4] is 5
arr [5] is 32766
The application runs, there is no ‘IndexOutOfBoundsException’.
SegFault
Lets write to a piece of memory where we don’t have access to. The program will crash. This is caused by the program trying to write to a piece of memory (segment) that is illegal. In C that is quite easy to do.
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5};
printf("arr [0] is %dn", arr[0]);
printf("arr [1] is %dn", arr[1]);
printf("arr [2] is %dn", arr[2]);
printf("arr [3] is %dn", arr[3]);
printf("arr [4] is %dn", arr[4]);
// crash segfault
arr[6] = 7;
printf("arr [6] is %dn", arr[6]);
return 0;
}
Lets compile and run:
$ gcc -Wall segfault.c -o segfault
./segfault
make: *** [run] Abort trap: 6
C++
Lets try something simmilar with C++.
#include <iostream>
int main()
{
std::cout << "Hello, World!";
return 0;
}
On a Mac, you don’t have to install anything, The C++ compiler is already available so you can just type the following.
$ g++ -Wall hello.cpp -o hello
$ ./hello
Hello, world!
# determine file type
$ file hello
hello: Mach-O 64-bit executable x86_64
# determine file size
$ ls -alh hello
-rwxr-xr-x 1 dennis staff 15K Nov 28 17:48 hello
Unsafe operations
Lets try something unsafe! Lets create an array with 5 elements, and lets access the 6th element. What will happen?
#include <iostream>
int main()
{
int arr[] = {1,2,3,4,5};
std::printf("arr [0] is %dn", arr[0]);
std::printf("arr [1] is %dn", arr[1]);
std::printf("arr [2] is %dn", arr[2]);
std::printf("arr [3] is %dn", arr[3]);
std::printf("arr [4] is %dn", arr[4]);
// surprise!!
std::printf("arr [5] is %dn", arr[5]);
return 0;
}
Outputs:
$ g++ -Wall unsafe.cpp -o unsafe
$ ./unsafe
arr [0] is 1
arr [1] is 2
arr [2] is 3
arr [3] is 4
arr [4] is 5
arr [5] is 32766
The same happened as in C.
SegFault
Lets try the segmentation fault in C++
#include <iostream>
int main()
{
int arr[] = {1,2,3,4,5};
std::printf("arr [0] is %dn", arr[0]);
std::printf("arr [1] is %dn", arr[1]);
std::printf("arr [2] is %dn", arr[2]);
std::printf("arr [3] is %dn", arr[3]);
std::printf("arr [4] is %dn", arr[4]);
// crash segfault
arr[6] = 5;
std::printf("arr [6] is %dn", arr[6]);
return 0;
}
Outputs:
$ gcc -Wall segfault.cpp -o segfault
./segfault
make: *** [run] Abort trap: 6
Conclusion
In this blog we’ve tried creating a couple of small programs. We have created helloworld in both C and C++ and that worked great. Both languages created very small binaries and started immediately. We then tried to do something unsafe and read an out of bounds memory location from an array. The compiler still created a binary, and allowed an out of bounds operation. Lastly we wrote to an out of bounds memory location that resulted in a segmentation fault, the application crashed.
Of course these are trivial examples and the error is easy to spot and easy to fix. When the codebase is larger, fixing the application becomes more difficult. C and C++, they brought us this far, but its time for more modern languages that help us catching these errors, and still allow us to create high performance applications.
Next time we’ll look at the Rust programming language that is a modern alternative to C and C++. Now that we have looked back, its time to move forward!