A program is a block of binary sequences. Nothing more and nothing less. Those sequences of binary patterns are contained in files that the hardware loads into electronic units. A much larger block of binary sequences have a say in what that program will do. The operating system. Compiling is more than using a tool to convert text source code into binary sequences. The program has to meet the standards of the operating system and connect with resources kept in other blocks of binary sequences. Milan Stevanovic wrote a book that shows the how and why of governing the way source code is converted to machine ready programs.
Code, Compile and Run
The knowledge in the book is not necessary in highly structured scenarios. Software built-in environments where all the machines that will run a software will have shared objects in the same locations, configured a common way can avoid most of what is written. Code can be written, compiled to binary files, and ran as they are often done.
The greatest benefit of this book is the methodology and background knowledge useful for inspecting binary files. The book is not really about C or C++. Those are simply the languages used as the specification inputs into the compilers and linkers that produce the binary files. The book is about the means, methods, and observations involved in decoding the binary files that are made. The trade-offs involved in certain compiler options. Understanding what the binary file actually encoded and what resources in terms of versions, file locations, and naming standards.
Usefulness of the Knowledge
Source code is written and a question looms, which Windows DLL or Linux Shared Object will the program load? Milan Stevanovic shows that some locations gets hardwired in such a way as to cause problems in some scenarios. He reveals what tools to use and how to decide which strategy to use, static compile or dynamic load, in the formation of the binary program.
Binary Interfaces and Compile/Link Flags Matter
The principle lesson is how to influence the design of binary libraries and executables. That is achieved using the source code, compilers, linkers, and various utility programs. The book could have been twice as large when it comes to the background information in the first couple of chapters. Though that could be a weakness, the information is well covered in other places. The observation of the details of binary outputs is the real value. At the end of the day, that is what is running on the system.
Those who alternate between a full day’s activity and periodic engagement with the material will find it takes some time to fully absorb what is written. All the information is useful and the progression is complete. More can be learned by trying out the examples.
The effort does pay off. I chose the book out of pure curiosity. I wondered if the knowledge would lead to improvement in my own projects. It did.
I used the knowledge in real-time to improve the make file and compiled result for a project I host on GitHub. That occurred somewhere in chapter 5 for 6 when I decided to experiment with what I was reading. The improvements I achieved was entirely unexpected and probably strengthened my engagement with the material.
Anyone who uses compilers and linkers, even indirectly through integrated development environments, can read the material and benefit from the methodology. The knowledge shared in the book can improve software design, preventative control over a class of run time defects; and the indirect troubleshooting insights that follow. Quality control of software results is the underlying result and on that basis, the book is highly recommended.