Presentation is loading. Please wait.

Presentation is loading. Please wait.

Separate Compilation.

Similar presentations


Presentation on theme: "Separate Compilation."— Presentation transcript:

1 Separate Compilation

2 A key concept in programming
Two kinds of languages, compilation (C, Pascal, …) and interpretation (Lisp, …, Matlab, Phython, Javascript…) It was a ‘milestone’ for procedural programming, some old ones like Pascal cannot, … It is in fact a kind of ‘abstract data type’, to separate the function “implementations” from its “definitions” It is also impossible for large projet without it

3 Translating a Library Program Source File Program Object File
C++ Compiler .o g++ -c Library Header File Linker Program Executable File C++ Compiler .o e.g., g++ foo.cpp bar.o fb.o Library Implementation File Library Object File g++ -c 3

4 Motivation #include <iostream> using namespace std;
bool even(int); bool odd(int x) { bool res; if(x == 0) res=false; else even(x-1); return res; } bool even(int x) { if (x == 0) res=true; else odd(x-1); int main() int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0;

5 It’s about ‘Organization’, organization of files!
#include <iostream> using namespace std; bool even(int); bool odd(int); int main() { int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0; } bool odd(int x) bool res; if(x == 0) res=false; else even(x-1); return res; bool even(int x) { if (x == 0) res=true; else odd(x-1); It’s about ‘Organization’, organization of files!

6 One file  many files … 3 functions: odd() even() main() even() main()
“main.cpp” even() “even.cpp” main() “main.cpp” odd() “odd.cpp” Reasons: 1. Reuse code for other programs 2. Divide work among programmers 3. Better maintenance, localize changes

7 odd() even() main() “odd.cpp” “even.cpp” “main.cpp” }
#include <iostream> using namespace std; bool odd(int); bool even(int); int main() { int x; while (cin >> x) num_calls = 0; cout << boolalpha << odd(x) << endl; } return 0; #include <iostream> using namespace std; bool odd(int); bool even(int x) { } #include <iostream> using namespace std; bool even(int); bool odd(int x) { }

8 g++ file.cpp  a.out g++ -c main.cpp  main.o g++ -c even.cpp  even.o g++ -c odd.cpp  odd.o g++ -o odd-even main.o even.o odd.o  odd-even -c generates an object file -o generates an executable by linking all object files

9 Separate compilation by ‘makefile’
If only “main.cpp” is modified, just need to re-compile “main.cpp” and re-link by: g++ -c main.cpp g++ -o odd-even main.o even.o odd.o No need to re-compile the object files, i.e. even.o and odd.o ‘makefile’ will automate all these things!!! ‘makefile’ is also a program in ‘script’ language that organizes your ‘command files’!

10 Using header files Many declarations are repeated in “odd.cpp” and “even.cpp”, but We do not want to repeat writing the same declarations in multiple files. Should a declaration require updating, one has to go through all files that have the declaration and make the change. More importantly, maintaining duplicate information in multiple files is error-prone.

11 #include preprocessor directive
include header files Instructs C++ preprocessor to replace directive with a copy of the contents of the specified file Quotes for user-defined header files Preprocessor first looks in current directory If the file is not found, looks in C++ Standard Library directory Angle brackets for C++ Standard Library Preprocessor looks only in C++ Standard Library directory #include <iostream> 11

12 Example of headfile myInclude.h main.cpp odd.cpp even.cpp
#include <iostream> using namespace std; bool even(int); bool odd(int x) myInclude.h main.cpp odd.cpp even.cpp #include “myInclude.h” int main() { int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0; } #include “myInclude.h” bool even(int x) { bool res; if (x == 0) res=true; else odd(x-1); return res; } #include “myInclude.h” bool odd(int x) { bool res; if(x == 0) res=false; else even(x-1); return res; }

13 Avoiding recursive inclusions …
It is ok to have multiple declarations of a function prototype, but not for its definition In the .h file, put the prototypes there .h files are likely to be multiply-included In creating the .o file, there may be nested #include statement The nested #include statement may be recursive In main.cpp, #include “foo.h” In foo.h, #include “bar.h” In bar.h, #include “foo.h” To break the infinite “recursive” inclusion, use #ifndefine #define to define a “variable” in the compilation process of .o file If a variable has been defined, the compiler will skip the code segment between #ifndefine and #endif. 13

14 #define preprocessor directive
if XYZ is undefined, we process the file. Otherwise we do not process the file (jumping to the #endif). XYZ should not appear in any other files. #ifndef XYZ #define XYZ f1(); f2(); #endif 14

15 File scope: external/internal
Each file must know the existence of every variable, constant and function that it uses! Global constants: repeat their definitions (global constants are ‘local’ to the file, internal!) External (global) variables: add keyword “extern” External functions: add function prototypes (with or without “extern”) “extern”  it’s (just) a declaration, but not a definition! equivalently, it means the variable / function is global and is defined in another file.

16 library.h main.cpp source.cpp Output:Hello 199 extern int Int;
int f(int); main.cpp source.cpp #include <iostream> #include "library.h" using namespace std; int Int=99; int main(){ cout << "Hello"<<endl; cout << f(100) << endl; return 0; } #include "library.h" int f(int i){ return (Int + i); } Output:Hello 199 16


Download ppt "Separate Compilation."

Similar presentations


Ads by Google