History of C++
==============


- Origins:

          Assembly -> BCPL -> C           -> D
                                  -> C++
             Algol -> Algol68             -> Java
           Fortran -> Simula67            -> C#


- Timeline:

    - Bjarne Stroustrup

    - C with Classes  1980

        Object-orientation
        Constructor/destructor


    - C++ since 1983

        Multiple inheritance


    - Support for generic programming

        Generic programming: Aleksey Stepanov 1985

        First with MACROs
        Template   since 1989

        Stepanov & Musser: Standard Template Library (STL)


    - Exceptions    since 1991

        ML-style exceptions are part of the type system


    - ISO standardisation process   since 1991

        The Annotated Reference Manual (ARM) (with M. Ellis)  1990
        The Design and Evolution of C++   1994

        C++98   ISO/IEC 14882:1998
        Misising: hash tables, smart pointers, threading

        C++03   minor bugfixes (like std::vector storage)
        Boost libraries (www.boost.org) -> TR1

        C++11   major language revision
        http://aszt.inf.elte.hu/~gsd/multiparadigm/draft-cpp11/cpp_draft_n3290.pdf
        move semantics, lambdas, constexpr, threading, auto
        hash tables, smart pointers, etc.

        C++14   minor revision
        http://aszt.inf.elte.hu/~gsd/multiparadigm/draft-cpp14/cpp14_draft.pdf

        C++17   new major release

- Design goals:

    - Type safety

        C++ is a statically, strongly typed programming language
        The compiler decides the type of all (sub)expression in compile time

        In run time: pointers, conversions, Object-oriented constructs


    - Resource safety

        Not just memory! All resources (files, sockets, locks, etc.)
        No garbage collection by def. (but can implement)
        Use the RAII (Resource Acquisition Is Initialization) idiom

        Most beginner makes resource errors

    - Performance

        Direct access to HW resources. No virtual machine
        High performance trading, phone exchange systems
        Low energy cosumption (Mars rover)

    - Predictability

        Large systems (2-10 million eLoC)
        Orthogonal features should work well together

    - Learnability, readability

        C++11: from expert-friendly to novice-friendly



Compiling, linking, executing
=============================


  preprocessing   compiling         linking   executing

header      source      object       library

  a.h
  b.h   ->   b.cpp   ->   b.o  ---------|
                                        ----->   a./out  (b.exe)
  e.h                                   |            |
  f.h   ->   d.cpp   ->   d.o  ---------|            |runtime
                                        |            |
  g.h   ->   g.cpp   ->   g.o           |            |
  h.h   ->   h.cpp   ->   h.o    ->   h.a  (h.lib)   |
                                       archive       |
  i.h   ->   i.cpp   ->   i.o                        |
  j.h   ->   j.cpp   ->   j.o    ->   j.so (j.dll) --|
                                      shared object





$ cat first.cpp

#include <iostream>

int main()
{
  std::cout << "hello world" << std::endl;
  return 0;
}



// compile + link
$ g++  first.cpp

// execute
$ ./a.out


// compile + link + set warnings on
$ g++ -ansi -pedantic -Wall first.cpp


// c++11 mode
$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp


// set output name to a.exe
$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp -o a.exe


// compile only
$ g++ -c  first.cpp
$ ls
a.o


// will call the linker 
$ g++ a.o


// calls the compiler for all sources then calls the linker
$ g++ a.c b.c d.o e.a f.so




//
//  using "using"
//

#include <iostream>

using std::cout;
using std::endl;

int main()
{
  cout << "hello world" << endl;
  return 0;
}




//
//  using "using" the wrong way
//

#include <iostream>

using std::cout, std::endl;

int main()
{
  cout << "hello world" << endl;
  return 0;
}

$ g++ -std=c++11 -ansi -pedantic -Wall first.cpp
first.cpp:3:16: error: expected ‘;’ before ‘,’ token
first.cpp:3:16: error: expected unqualified-id before ‘,’ token
first.cpp:3:27: error: expected constructor, destructor, or type conversion before ‘;’ token
first.cpp: In function ‘int main()’:
first.cpp:7:28: error: ‘endl’ was not declared in this scope
first.cpp:7:28: note: suggested alternative:
In file included from /usr/include/c++/4.7/iostream:40:0,
                 from first.cpp:1:
/usr/include/c++/4.7/ostream:562:5: note:   ‘std::endl’




//
//  using "using namespace"
//

#include <iostream>

using namespace std;

int main()
{
  cout << "hello world" << endl;
  return 0;
}







//
// fahr2cels: convert fahrenheit to celsius in [-100 ... 400] step 20
// the bad 
//

#include <iostream>

int main()
{
  for( int fahr = -100; fahr <= 400; fahr += 20 )
  {
    std::cout << "fahr = " << fahr
              << ", cels = " << 5/9 * (fahr-32)
              << std::endl;
  }
  return 0;
}




$ g++ -std=c++11 -ansi -pedantic -Wall fahr2cels.cpp



$ ./a.out
fahr = -100, cels = 0
fahr = -80, cels = 0
fahr = -60, cels = 0
fahr = -40, cels = 0
fahr = -20, cels = 0
fahr = 0, cels = 0
fahr = 20, cels = 0
fahr = 40, cels = 0
fahr = 60, cels = 0
fahr = 80, cels = 0
fahr = 100, cels = 0
fahr = 120, cels = 0
fahr = 140, cels = 0
fahr = 160, cels = 0
fahr = 180, cels = 0
fahr = 200, cels = 0
fahr = 220, cels = 0
fahr = 240, cels = 0
fahr = 260, cels = 0
fahr = 280, cels = 0
fahr = 300, cels = 0
fahr = 320, cels = 0
fahr = 340, cels = 0
fahr = 360, cels = 0
fahr = 380, cels = 0
fahr = 400, cels = 0





//
// fahr2cels: convert fahrenheit to celsius in [-100 ... 400] step 20
// the ugly
//

#include <iostream>

int main()
{
  for( int fahr = -100; fahr <= 400; fahr += 20 )
  {
    std::cout << "fahr = " << fahr
              << ", cels = " << 5./9. * (fahr-32)
              << std::endl;
  }
  return 0;
}


$ ./a.out
fahr = -100, cels = -73.3333
fahr = -80, cels = -62.2222
fahr = -60, cels = -51.1111
fahr = -40, cels = -40
fahr = -20, cels = -28.8889
fahr = 0, cels = -17.7778
fahr = 20, cels = -6.66667
fahr = 40, cels = 4.44444
fahr = 60, cels = 15.5556
fahr = 80, cels = 26.6667
fahr = 100, cels = 37.7778
fahr = 120, cels = 48.8889
fahr = 140, cels = 60
fahr = 160, cels = 71.1111
fahr = 180, cels = 82.2222
fahr = 200, cels = 93.3333
fahr = 220, cels = 104.444
fahr = 240, cels = 115.556
fahr = 260, cels = 126.667
fahr = 280, cels = 137.778
fahr = 300, cels = 148.889
fahr = 320, cels = 160
fahr = 340, cels = 171.111
fahr = 360, cels = 182.222
fahr = 380, cels = 193.333
fahr = 400, cels = 204.444





//
// fahr2cels: convert fahrenheit to celsius in [-100 ... 400] step 20
// the good 
//

#include <iostream>
#include <iomanip>

int main()
{
  for( int fahr = -100; fahr <= 400; fahr += 20 )
  {
    std::cout << "fahr = " << std::setw(5) << fahr
              << ", cels = " << std::setw(8) << 5./9. * (fahr-32)
              << std::endl;
  }
  return 0;
}



$ ./a.out
fahr =  -100, cels = -73.3333
fahr =   -80, cels = -62.2222
fahr =   -60, cels = -51.1111
fahr =   -40, cels =      -40
fahr =   -20, cels = -28.8889
fahr =     0, cels = -17.7778
fahr =    20, cels = -6.66667
fahr =    40, cels =  4.44444
fahr =    60, cels =  15.5556
fahr =    80, cels =  26.6667
fahr =   100, cels =  37.7778
fahr =   120, cels =  48.8889
fahr =   140, cels =       60
fahr =   160, cels =  71.1111
fahr =   180, cels =  82.2222
fahr =   200, cels =  93.3333
fahr =   220, cels =  104.444
fahr =   240, cels =  115.556
fahr =   260, cels =  126.667
fahr =   280, cels =  137.778
fahr =   300, cels =  148.889
fahr =   320, cels =      160
fahr =   340, cels =  171.111
fahr =   360, cels =  182.222
fahr =   380, cels =  193.333
fahr =   400, cels =  204.444






//
// fahr2cels: convert fahrenheit to celsius in [-100 ... 400] step 20
// fixed, setprecision, setw 
//

#include <iostream>
#include <iomanip>

int main()
{
  for( int fahr = -100; fahr <= 400; fahr += 20 )
  {
    std::cout << "fahr = " << std::setw(4) << fahr
              << ", cels = " << std::fixed << std::setw(7)
              << std::setprecision(2) << 5./9. * (fahr-32)
              << std::endl;
  }
  return 0;
}



$ ./a.out
fahr = -100, cels =  -73.33
fahr =  -80, cels =  -62.22
fahr =  -60, cels =  -51.11
fahr =  -40, cels =  -40.00
fahr =  -20, cels =  -28.89
fahr =    0, cels =  -17.78
fahr =   20, cels =   -6.67
fahr =   40, cels =    4.44
fahr =   60, cels =   15.56
fahr =   80, cels =   26.67
fahr =  100, cels =   37.78
fahr =  120, cels =   48.89
fahr =  140, cels =   60.00
fahr =  160, cels =   71.11
fahr =  180, cels =   82.22
fahr =  200, cels =   93.33
fahr =  220, cels =  104.44
fahr =  240, cels =  115.56
fahr =  260, cels =  126.67
fahr =  280, cels =  137.78
fahr =  300, cels =  148.89
fahr =  320, cels =  160.00
fahr =  340, cels =  171.11
fahr =  360, cels =  182.22
fahr =  380, cels =  193.33
fahr =  400, cels =  204.44




//
// fahr2cels: using const
//

#include <iostream>
#include <iomanip>

const int lower = -100;
const int upper =  400;
const int step  =   40;

int main()
{
  for( int fahr = lower; fahr <= upper; fahr += step )
  {
    std::cout << "fahr = " << std::setw(4) << fahr
              << ", cels = " << std::fixed << std::setw(7)
              << std::setprecision(2) << 5./9. * (fahr-32)
              << std::endl;
  }
  return 0;
}







//
// fahr2cels: with function call
//

#include <iostream>
#include <iomanip>

const int lower = -100;
const int upper =  400;
const int step  =   20;

// declaration of the fahr2cels function
double fahr2cels(double);

int main()
{
  for( int fahr = lower; fahr <= upper; fahr += step )
  {
    std::cout << "fahr = " << std::setw(4) << fahr
              << ", cels = " << std::fixed << std::setw(7)
              << std::setprecision(2)
              << fahr2cels(fahr)  // call of fahr2cels(double)
              << std::endl;
  }
  return 0;
}


// definition of the fahr2cels function
double fahr2cels(double f)
{
  return 5./9. * (f-32);
}







//
// meteo.h
//

double fahr2cels( double f);





//
// meteo.cpp
//

#include "meteo.h"

// definition of the fahr2cels function
double fahr2cels(double f)
{
  return 5./9. * (f-32);
}




//
// fahr2cels: separate sources
//

#include <iostream>
#include <iomanip>
#include "meteo.h"  // for fahr2cels(double)
                    // search meteo.h from current dir

const int lower = -100;
const int upper =  400;
const int step  =   20;

int main()
{
  for( int fahr = lower; fahr <= upper; fahr += step )
  {
    std::cout << "fahr = " << std::setw(4) << fahr
              << ", cels = " << std::fixed << std::setw(7)
              << std::setprecision(2)
              << fahr2cels(fahr)  // call of fahr2cels(double)
              << std::endl;
  }
  return 0;
}



$ g++ -std=c++11 -ansi -pedantic -Wall fahr2cels.cpp
/tmp/ccijFVjc.o: In function `main':
fahr2cels.cpp:(.text+0x21): undefined reference to `fahr2cels(double)'
collect2: error: ld returned 1 exit status



$ g++ -std=c++11 -ansi -pedantic -Wall -c meteo.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall -c fahr2cels.cpp
$ g++ -std=c++11 -ansi -pedantic -Wall meteo.o fahr2cels.o

$ ./a.out



Homework:

1. Create a program printing your name. Compile, link, run.
2. Separate the program to 2 sources: one return the name, other prints
   Hints:
   - use std::string class to hold your name.
   - std::string class is implemented in <string> header.
   - there is an automatic conversion from "c-style-strings" to std::string.