Module A - Introduction

Portable Programs

C | C++ | Compilation Stages | Platforms | Linking C and C++ Code | Exercise



A variety of platforms exists for running software applications.  As developers, we need to be aware of the platform upon which our programs will execute.  Ideally, they will recompile and run without any changes when we move them from one platform to another.  We call such programs fully portable.  If a program requires a change - hopefully, a minor setting in a header file - we call that program conditionally portable.  To maximize portability, we code to published language standards and use libraries that are available across a broad range of platforms. 

Language standards are agreements amongst compiler writers to implement minimally a common subset of a programming language.  If we restrict our coding to the published standard subset of a language, we may expect our applications to be conditionally portable to a high degree.

The C and C++ languages have separately defined standards and independent development histories. 


The C Language

Kernighan and Ritchie, in their first edition (1978) of "The C Programming Language", documented the first description of the C language.  We call this description "K&R" C.  Since then, the C language has undergone three major revisions: C89, C95 and C99. 


Standard C

C89

The International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC) adopted the first standard definition of the C language in ISO/IEC 9899:1990.  We call this C89 for short.  It provided:

  • function prototypes
  • a standard library
  • whitespace before # directives
The American National Standards Institute (ANSI) amended C89 in 1995, to include new conversion specifiers for printf and scanf as well as new library functions.

C99

The ISO/IEC approved the second standard definition of the C language in ISO/IEC 9899:1999 or C99 for short.  C99 includes, in addition to C89:

  • the long long data type
  • the _Bool data type
  • the _Complex data type
  • complex arithmetic
  • variable-length arrays
  • // style in-line comments
  • better support for floating-point types, including distinct math functions for each primitive data type

The latest publicly available version of the C99 is WG14N1124.


The C++ Language

Bjarne Stroustrup released the C++ language from Bell Labs (AT&T Research Labs) in October 1985.  The ++ is the C post-fix increment operator and stands for the addition of classes.  His definition is known as pre-standard C++.

Standard C++

The ISO/IEC approved the first standard definition for the C++ language in ISO/IEC 14882:1998.  This standard removed some features from the pre-standard definition, added some new features and deprecated some others.  The ISO/IEC has since revised its document (2003).  A copy is available at The ANSI Store.  A more recent working draft is available at The ISO/IEC Site.

Standard C++ includes a fully rewritten stream library, a string class, constrained casts, and a comprehensive standard template library. 


Stages of Compilation

C and C++ are compiled languages.  Compilation is a multi-stage process.  A full compiler consists of a pre-processor, the compiler proper and a linker.  The complete process transforms source code into the executable machine language code in three steps:

  • the pre-processor takes the original source code, includes the externally declared prototypes, and expands the #define directives to create a compilable version of the source code,
  • the compiler proper translates the pre-processed source code modules into object code modules, and
  • the linker assembling all of the object modules and resolves all external references in each object code module by appending code from object libraries to create a single relocatable module.
The term object code used here bears no relation to the term object used in object-oriented programming. 

The loader loads the relocatable code into primary memory and transfers control to the entry point for the program.


Platforms

The platforms used in this course are:

  • Borland - 5.5 Win32 Compiler (x86)
  • .net - Microsoft cl 14.0 Win32 Compiler (x86)
  • GCC - GNU Compilers on matrix
  • AIX - xlC Visual Age Compilers on phobos

Borland

The Borland platform uses a fast compiler that is available for free.  Instructions for installing this compiler on your PC are in the resource section

To list the compiler options, open a command-line window on your local computer and enter


 bcc32

The options include
  • -c compile only no link, creates a .o object file. 
  • -oxxx compile and link, creates an executable file named xxx

.net

The .net platform uses the a compiler that is the core technology for the Visual Studio C++ Professional Development Environment.  This compiler is available for free.  Instructions for installing this compiler on your PC are in the resources section

To list the compiler options, open a Visual Studio command-line window and enter


 cl /help

The options include
  • /c compile only no link, creates a .obj object file. 
  • /E pre-process only, send output to stdout
  • /P pre-process only, send output to .i
  • /Wall enable all warnings. 

AIX

The AIX platform includes two compilers - cc and c++.  To use either, we will need a terminal emulator that turns our PC into a client of the host system.  phobos hosts the AIX platform.  Instructions for installing a terminal emulator for phobos are in the resources section

To list the compiler options, connect to phobos and at the command prompt enter either of


 cc
 c++

The options include
  • -c compile only no link, creates a .o object file. 
  • -E pre-process only, send output to stdout
  • -P pre-process only, send output to .i
  • -g produce information for the debugger (dbx). 

GCC

The GCC platform includes two compilers - gcc and g++.  To use either compiler, we will need a terminal emulator that turns our PC into a client of the host system.  matrix hosts the GCC platform.  Instructions for configuring a terminal emulator for matrix are in the resources section

To list the compiler options, connect to matrix and at the command prompt enter either of


 gcc --help
 g++ --help

The options include
  • -c compile only no link, creates a .o object file. 
  • -E pre-process only, send output to stdout
  • -g produce information for the debugger (gdb). 


Linking C and C++ Code

C and C++ compilers create different object code from the same source code.  Specifically, they create different external symbols for function names.  C compilers keep the function names intact, while C++ compilers mangle the function names to enable overloading. 

This difference between the compilers causes compatibility issues when linking a function compiled under a C compiler with a function compiled under a C++ compiler.  For example, consider the following C implementation file


 /* Cross-Compilation
  * C library function
  * hello.c
  * Sep 7 2005
  */

 #include <stdio.h>

 void hello(const char *s) {
     printf("Hello %s\n", s);
 }

and its associated header file


 /* Cross-Compilation
  * C library function
  * hello.h
  * Sep 7 2005
  */

 void hello(const char *);

On the Borland platform, this source file compiles successfully into the object code module named hello.obj:


 bcc32 -c hello.c

Let us try to link the object code module hello.obj with the following C++ application:


 /* Cross-Compilation
  * Calling Function
  * caller.cpp
  * Sep 7 2005
  */

 #include "hello.h"  /* LINKAGE ERROR */ 

 int main(void) {
     hello("OOP344");
     return 0;
 }

On the Borland platform, this main function compiles successfully


 bcc32 caller.cpp hello.obj

but the linker stage fails.  This failure is due to an unresolved external reference:


 Error: Unresolved external 'hello(const char *)'

The linker cannot resolve the reference to hello in caller.cpp using the object code module hello.obj.  The symbol for hello in caller.cpp is mangled, while the symbol for hello in hello.obj is not mangled. 

To resolve this incompatibility, we direct the linker to use the "C" linkage convention rather than the C++ convention in linking hello.obj to caller.obj.  We do so by wrapping the include directive in a linker declaration:


 /* Cross-Compilation
  * Calling Function
  * caller.cpp
  * Sep 7 2005
  */

 extern "C" {            /* identifies C linkage convention */ 
     #include "hello.h"
 }

 int main(void) {
     hello("OOP344");
     return 0;
 }

With this declaration our C and C++ modules link successfully.


Exercises

  • Install the bcc32 and cl compilers on your PC
  • Confirm that you can successfully compile and link the hello application on all platforms in this course
  • Read pages 1-9 from Evan Weaver's subject notes
  • Read about portability in Wikipedia




   Printer Friendly Version of this Page print this page     Top  Go Back to the Top of this Page
Previous Reading  Previous: Table of Contents Next: Macros   Next Reading


  Designed by Chris Szalwinski   Copying From This Site