Java goes through a single compilation step to translate source code (.java) to bytecode (.class). C++ goes through a few more steps to reach binary code. (.exe/.dll)
Source Code (.c) -> PREPROCESSOR -> COMPILER -> Assembly Code (.o)
Assembly Code (.o) -> LINKER (+Libraries) -> Executable Code (.exe/.dll)
The Preprocessor processes # preprocessor directives. For example this will #include the contents of the header file into this position. #define will define pre-processor variables, do substitution and include only relevant #ifdef sections.
The compiler will then translate source code into assembly code, similar to the Java compiler step. This step will catch all syntax errors. The compiler should be able to locate all #include files through the additional include directories specified by the /I command line.
The linker then produces the binary for the assembly code. Linker errors can occur here if the compiled libraries referenced are not found.
The end result of a compilation/linking is usually an .exe file, which can be directly executed on a Windows machine. There are also options to create a dynamic library (dll) or a static library (lib). A dynamic library is looked up at runtime, and is usually shared among multiple programs. A static library is compiled into the executable directly, and does not require the existance of the lib during execution. A program referencing a DLL library will be smaller than one referencing a LIB, since the DLL code is located inside the DLL.
To call another method, the method must be “declared” before the calling line. Declaration may mean the actual method implementation, or just a “header” specifying the method name and parameters. Thus the use of #include files often at the top which includes the method definitions so they may be referenced. Actual implementation is later linked using the linker.
(Warning: This is an incoherent post – there has been no attempt to organize the paragraphs such that it flows in a thoughtful manner. These thoughts just poured out of my mind at that moment in time…)
Software Testing is important to maintain the quality of software produced. Good testing is difficult, hindered by time, management, and possibly testing techniques.
To me, good tests must be documented. This may come in the simple form of documented test cases, although I seriously prefer automated tests to perform those test cases. Automated tests are usually run more often, as compared to needing people to sit and key in pre-defined input and check outputs.
Using human as testers have an additional advantage, they help to introduce human error. Good software should be able to recover and remain stable under human error conditions (prefably all kinds of error conditions) To simulate this situation, automated tests should introduce elements of randomness. For example, free text input such as text boxes should be tested with all possible input characters from the keyboard, as well as random combination of input keys. The former ensures that the system is able to handle all characters, and the latter simulates “a monkey banging the keyboard”.
Applying randomness in testing catches more errors than if you always used fixed input, say “John Smith” for full names. Or even worse, “test” as a full name. Can your system accept “Thomas D’Cruz”? Or a 94-character long indian full name? Yet once you catch an error with random input, are you able to reproduce the same input to verify that your system has handled that case?
This is a common flaw when doing automated random testing. Test sequences MUST be logged (to files) so that the errorneous test can be repeated with the exact same input so that the bug can be verified (as a bug) and verified (as fixed). Although threaded programs may not return you the same output given those same input, the information will also serve as a debug log that will assist you in reproducing the error. If the error cannot be reproduced, it cannot be verified.
Using frameworks such as JUnit will assist you in combining several tests into a test suite so that automatic regression testing is simplified. Hopefully every refactor or change to the base source can be accompanied by a test run.
No entry for the last week, was getting used to my new work environment. Due to the shift to technologies like SWT and XMPP, my posts will be rather geared towards those topics. For now, I’ll need to understand SWT:
– How to access shells and displays correctly
– How to create and use simple SWT widgets
– Managing/swtiching between windows and composites
– SWT layouts, maybe creating SWT-AWT layout adapters