C++ vs. Rust: Security, Performance, and Development Analysis

Verified

Added on  2019/09/16

|4
|1387
|439
Homework Assignment
AI Summary
This assignment presents a comparative analysis of C++ and Rust, two prominent programming languages. The solution begins by highlighting the historical context of null references in C++ and their potential to introduce complexity and security vulnerabilities, using code examples to illustrate these issues. The assignment then transitions to Rust, emphasizing its design for memory safety through compile-time checks, ownership, and the elimination of data races, contrasting its approach with C++. Furthermore, the solution explores how Rust's features, such as thread safety, trait-based generics, and type inference, contribute to secure coding practices. Finally, the assignment concludes with a recommendation for choosing between C++ and Rust for software development in a large company, considering factors such as language stability, available tools, programmer availability, performance, and the maturity of the ecosystem. The recommendation favors C++ due to its established status, extensive tool support, and the pragmatic need for a stable language with a large developer base, while acknowledging Rust's superior security features.
Document Page
Answer 1
Tony Hoare, who invented null references in ALGOL W programming language, in 1965 refers
to it as a "historically bad idea", a "billion-dollar mistake". The impetus for him to introduce this
feature was a typical programmer tendency to incorporate a new unrequested feature in the
product he is working on, just because it is easy to implement.
Now, let us explore how null references can cause complexities and create insecure code, with
reference to C and C++.
(1) Complexity increases because any object can in theory be null, and throw an exception when
it is used. This results in the code being a collection of bombs which could explode any time.
Now, to mitigate this, checks have to introduced at every step which ensure that the object we
are dealing with is not null, and only then we proceed with accessing its members or properties.
Code example:
...
stream = open_memstream(&buf, &size);
if (stream == NULL) { // checking error
/* handle error */
};
fprintf(stream, "hello");
...
(2) Security concerns are introduced as NULL being a value that denotes no value, it is able to
bypass compile-time checks of compiler.
Code example:
char c = 'A';
char *myChar = 0; // instead of &c
std::cout << *myChar << std::endl; // results in runtime error
(3) Security is compromised as because of null reference, strings are identified by their being
terminated by null character. There is nothing stopping a programmer from accessing memory
outside the bounds of the string. This opens up security as anything can be read or written to any
memory location.
Code example:
char myText = "Hello";
myText[10] = 'c'; // writing on unauthorized out-of-bound memory location
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
(4) Security is further compromised when NULL is considered with freeing memory. Now, when
memory is attempted to be freed from a location which has already been freed, undefined
behavior occurs and the system behaves in an unexpected manner.
Code example:
free(x); // this is wrong
/* code using x */
free(x);
Now, there are conventions and best-practices that train programmers to work around these
loopholes, but the fact is that they do exist, and they all stem from the one decision to include
null references.
Answer 2
Rust has been developed to be a more secure language than contemporary languages which focus
on programs being able to be embedded in other languages, with specific space and time
requirements, and writing low-level code, like device drivers and operating systems. It intends
to be more secure by introducing a number of compile-time safety checks which have zero
runtime overhead, and also eliminates data races.
Memory safety is guaranteed in Rust by taking away all control of managing memory away from
the user and giving it back to the programming language. While this not only reduces the burden
on programmers, it ensures a whole class of security loopholes are eliminated. The programmer
does not do any pointer arithmetic or managing memory (no 'free' is required to deallocate
memory in Rust). When an entity goes out of scope, the memory allocated to it is reclaimed.
Also, the concept of ownership ensures that at any given time, only one entity has access to a
memory location and this eliminates races, and contributes to memory safety.
Code example in Rust:
let text = "hello world";
println!("Exists {:?}", text);
println!("Does not exist {:?}", text_no_binding); // will result in compile-
time error as variable has not been bound
Code example in C:
int x;
printf("%d", x); // indeterminate, undefined behavior will result
Document Page
Answer 3
Rust provides many features to improve secure coding, like threads without races, trait-based
generics, type inference. They help improve secure coding, as explained below:
Threads without races
In a multi-threading programming language, multiple threads race among them to access and
change the same piece of data. As the language's scheduling algorithm treats the data as stable
and can swap between threads at any time, we are not sure which thread gets to access the data
first, and just like global variables (which can be modified from any part of the program) in a
program, cannot rely on it. Now, Rust eliminates this problem with the concept of ownership.
Eliminating race allows the program to be reliable as the programmer can be sure that who has
the authority to change a piece of data, and thus eliminates the randomness of the race
conditions.
C++ uses mutex to guard against race condition in multithreading, but does not cover all
scenarios and steps have to be taken to ensure that the data is protected properly.
Trait-based generics
Traits are utilized in creating template code which can be reused in many different scenarios. It
helps in a more secure code by taking the guesswork out of types in code reuse and returning a
function as per the parameters passed. Thus, at compile time, better decisions can be made as the
information about the types and their handling is available. Without this facility, it is possible for
errors to slip, especially in template programming.
As of C++11, a new 'static_assert' functionality uses compile-time constant expressions to check
for errors.
Type inference
Without type inference, compiler does not know what data types it is actually dealing with at the
compile-time, and this allows for insecure coding to pass through compiler checks. However,
type inference is difficult in low-level programming languages, as the low-level code has to deal
with a lot of untyped things.
C++ introduces type inference with 'auto' keyword in C++11, but before that the type of a
variable must be declared explicitly.
Answer 4
Given a choice between C++ and Rust for development of a new software in a large company, I
would recommend going for C++, due to following reasons:
(1) C++ is a stable programming language with a relatively huge supply of programmers
available.
Document Page
(2) Being an old language - and having operating systems, compilers, device drivers, Web
browsers written it - it has a wide variety of free and commercial tools to aid development,
testing and deployment of software.
(3) C++ is an accommodating language for someone wanting to write insecure code, but decades
of programming real systems, education by academicians, conventions by programmers provide
a framework to guide the programming effort to write secure and simple code. The reason why
Rust, which is a more secure language, loses is the runtime performance. Few programming
languages have been able to compete with C/C++ in performance.
(4) As the state of industry is, it is unadvisable for a commercial company to commit resources
into development of a commercial software in relatively new programming language, which has
less tools (Integrated Development Environments (IDE)), debuggers, and most importantly
skilled programmers. For a hobby project, I would be less hesitant to try Rust.
Thus, considering all the factors above and the scenario for which my opinion is being sought, I
have to pragmatic in my reasoning, and would categorically advise in favor of C++.
chevron_up_icon
1 out of 4
circle_padding
hide_on_mobile
zoom_out_icon
[object Object]