Executable program (p1)

Slides:



Advertisements
Similar presentations
Chapter 11 Separate Compilation and Namespaces. Copyright © 2006 Pearson Addison-Wesley. All rights reserved Learning Objectives Separate Compilation.
Advertisements

Copyright © 2002 Pearson Education, Inc. Slide 1.
Compilation and Debugging 101. Compilation in C/C++ hello.c Preprocessor Compiler stdio.h tmpXQ.i (C code) hello.o (object file)
CSE 303 Lecture 16 Multi-file (larger) programs
David Notkin Autumn 2009 CSE303 Lecture 20 Multi-file (larger) programs Friday: social implications.
Chapter 11 Separate Compilation and Namespaces Copyright © 2008 Pearson Addison-Wesley. All rights reserved.
. Compilation / Pointers Debugging 101. Compilation in C/C++ hello.c Preprocessor Compiler stdio.h tmpXQ.i (C code) hello.o (object file)
 2006 Pearson Education, Inc. All rights reserved Introduction to Classes and Objects.
chap13 Chapter 13 Programming in the Large.
Copyright 2001 Oxford Consulting, Ltd1 January Storage Classes, Scope and Linkage Overview Focus is on the structure of a C++ program with –Multiple.
The Structure of a C++ Program. Outline 1. Separate Compilation 2. The # Preprocessor 3. Declarations and Definitions 4. Organizing Decls & Defs into.
Programming With C.
Chapter 6: User-Defined Functions
Fundamentals of C and C++ Programming. EEL 3801 – Lotzi Bölöni Sub-Topics  Basic Program Structure  Variables - Types and Declarations  Basic Program.
Compilation & Linking Computer Organization I 1 November 2009 © McQuain, Feng & Ribbens The Preprocessor When a C compiler is invoked, the.
Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system.
CSE 251 Dr. Charles B. Owen Programming in C1 Compilation and Makefiles.
Static Shared Library. Non-shared v.s. Shared Library A library is a collection of pre-written function calls. Using existing libraries can save a programmer.
15. WRITING LARGE PROGRAMS. Source Files A program may be divided into any number of source files. Source files have the extension.c by convention. Source.
Chapter 13 : Symbol Management in Linking
Week 4 - Friday.  What did we talk about last time?  Some extra systems programming stuff  Scope.
C Part 1 Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens A History Lesson Development of language by Dennis Ritchie at Bell.
LECTURE 3 Translation. PROCESS MEMORY There are four general areas of memory in a process. The text area contains the instructions for the application.
L071 Introduction to C Topics Compilation Using the gcc Compiler The Anatomy of a C Program Reading Sections
1 Building a program in C: Preprocessor, Compilation and Linkage.
Binding & Dynamic Linking Presented by: Raunak Sulekh(1013) Pooja Kapoor(1008)
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 18 – Linking and Libraries.
Introduction to GCC Department of Radio Physics and Electronics ILug-Cal Introduction to GCC Department of Radio Physics and Electronics, Calcutta University.
BIL 104E Introduction to Scientific and Engineering Computing Lecture 4.
Lecture 3 Translation.
Introduction to C Topics Compilation Using the gcc Compiler
Week 3-4 Control flow (review) Function definition Program Structures
Executable program (p1)
Chapter 5- Assembling , Linking, and Executing Programs
Algorithms Problem: Write pseudocode for a program that keeps asking the user to input integers until the user enters zero, and then determines and outputs.
Linking & Loading.
Functions Separate Compilation
Separate Assembly allows a program to be built from modules rather than a single source file assembler linker source file.
Program Execution in Linux
Introduction to C Topics Compilation Using the gcc Compiler
GCC: the GNU Compiler Collection
CS1010 Programming Methodology
Introduction to C Topics Compilation Using the gcc Compiler
The Preprocessor Based on Chapter 1 in C++ for Java Programmers by Weiss When a C compiler is invoked, the first thing that happens is that the code is.
CS1010 Programming Methodology
Choice of Programming Language
Chapter 6: Functions Copyright © 2010 Pearson Education, Inc. Publishing as Pearson Addison-Wesley.
6 Chapter Functions.
Functions, Part 1 of 3 Topics Using Predefined Functions
CSC 253 Lecture 6.
Separating Definition & Implementation
Introduction to Classes and Objects
Comments, Prototypes, Headers & Multiple Source Files
Creating your first C program
Linking.
Programming Fundamentals Lecture #3 Overview of Computer Programming
C++ Compilation Model C++ is a compiled language
Your first C and C++ programs
CSE 303 Concepts and Tools for Software Development
Writing Large Programs
Functions, Part 1 of 3 Topics Using Predefined Functions
C Preprocessor Seema Chandak.
What Is? function predefined, programmer-defined
Compiler vs linker The compiler translates one .c file into a .o file
Functions, Part 1 of 3 Topics Using Predefined Functions
CSC 253 Lecture 15.
Introduction to C Topics Compilation Using the gcc Compiler
The Three Attributes of an Identifier
GCC: the GNU Compiler Collection
SPL – PS1 Introduction to C++.
Presentation transcript:

Executable program (p1) Program Translation text C program (p1.c) Compiler (gcc -S) text Asm code (p1.s) Assembler (gcc or as) binary Object code (p1.o) Static libraries (.a) Linker (gcc or ld) binary Executable program (p1)

Typical C Program Organization I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. For very small programs, code is often organized in a single source file; the most common convention uses the extension c for C source files. // single file For more interesting C programs, the code is typically organized into a collection of header files (extension h) and source files. In most cases, the header files contain only type declarations and function prototypes, while the c files contain the corresponding implementations. // a.h // a.c // b.h // b.c // z.h // z.c . . . // main.c #include directives are used within both h and c files to “import” declarations as necessary.

The Build Process: Pre-processing I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. The C pre-processor will load the contents of #include'd header files into the .c files: // A.h #include "B.h" void A(); // B.h void B(); // C.h void C(); // main.c #include "A.h" #include "C.h" . . . // A.c #include "A.h" // B.c #include "B.h" // C.c #include "C.h" From this point, the .h files are of no concern to the compiler (or later stages).

The Build Process: Inclusions I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. // main.c void A(); void B(); void C(); void G(); . . . void F() { A(); // call B(); // call C(); // call G(); // call } void G() { // definition // A.c void A(); void B(); void A() { // definition B(); // call } // B.c void B(); void B() { // definition } // C.c void C(); void C() { // definition } Why would B.c #include B.h? - perhaps B.h #includes standard headers needed in B.c - perhaps B.h defines a type needed in B.c

The Build Process: Compilation I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. The compiler processes each .c file separately from the others. // main.c void A(); void B(); void C(); void G(); . . . void F() { A(); // call B(); // call C(); // call G(); // call } void G() { // definition // A.c void A(); void B(); void A() { // definition B(); // call } // B.c void B(); void B() { // definition } // C.c void C(); void C() { // definition } main.o A.o B.o C.o From each .c file the compiler produces an object file (.o).

The Build Process: Function Calls I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. The compiler needs to see a valid declaration for each called function: // main.c void A(); void B(); void C(); void G(); . . . void F() { A(); // call B(); // call C(); // call G(); // call } void G() { // definition // A.c void A(); void B(); void A() { // definition B(); // call } Solution: the inclusions solve that need

The Build Process: Function Calls I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. Each function call must be bound to the definition of the called function: // main.c void A(); void B(); void C(); void G(); . . . void F() { A(); // call B(); // call C(); // call G(); // call } void G() { // definition // A.c void A(); void B(); void A() { // definition B(); // call } // B.c void B(); void B() { // definition } // C.c void C(); void C() { // definition } Problem: for some calls, we must bind to code that's actually in a different object file: main.o A.o B.o C.o

The Build Process: External References I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. How do we bind a call in one file to a function definition in another? // main.c void A(); void B(); void C(); void G(); . . . void F() { A(); // call B(); // call C(); // call G(); // call } void G() { // definition // A.c void A(); void B(); void A() { // definition B(); // call } main.o compiler leaves a "tag" for each call from main.c to an "external" function: A() B() C() A.o compiler leaves a "tag" for each call from B.c to an "external" function: B()

The Build Process: Linking I use the term "module" to refer to a c/h pair, or more broadly to a collection of c/h files that define a coherent functional unit. It's the job of the linker to combine the separate object files into an executable: main.o A.o B.o C.o executable The linker also has to resolve any external references that were tagged by the compiler.

Controlling Access Often, a .c file includes some functions (and other things) that are needed only in that file: // B.c #include "B.h" int32_t B(int32_t x) { // do stuff Helper(); } static void Helper() { ... Here, B() calls Helper(), but no other functions outside of the file B.c do so… static void Helper(); So, we put the declaration of Helper() inside B.c, before any calls to it… and make it static… … and we do NOT declare Helper() in B.h: // B.h int32_t B(int32_t x);

The Multiple Inclusion Problem This often can happen when coalescing the pieces of a large system, where the pieces were implemented, and to some degree designed, by different developers. It is possible to create some unfortunate situations: // main.c #include "A.h" #include "B.h" Here, the preprocessor will copy the text of B.h into main.c twice, once due to the inclusion in A.h and once due to the explicit inclusion in main.c. This scenario is difficult to avoid in large projects involving many individuals or teams. However, there is a simple fix using preprocessor directives: // A.h #include "B.h" // B.h void foo(); // B.h #ifndef B_H #define B_H void foo(); . . . #endif

Example: Fibonacci Here's a short program with a test driver, a Fibonacci function in a second file, and a header file containing the declarations needed for the Fibonacci function: #ifndef RFIBONACCI_H #define RFIBONACCI_H #include <stdint.h> uint64_t rFibonacci(uint64_t n); #endif #include <stdio.h> #include <inttypes.h> #include "rFibonacci.h" int main() { for (int i = 0; i < 50; i++) { printf("Fibo(%d) = %"PRIu64"\n", i, rFibonacci(i)); } return 0; #include "rFibonacci.h" uint64_t rFibonacci(uint64_t n) { if ( n < 2 ) return 1; return rFibonacci(n - 1) + rFibonacci(n - 2); }

Compilation We can compile either c file without the other (but not produce an executable): CentOS> gcc -o driver -std=c99 -Wall -W driver.c rFibonacci.c CentOS> ls -l total 24 -rwxrw-r--. 1 wmcquain comporg 8578 Sep 25 10:21 driver -rw-rw-r--. 1 wmcquain comporg 216 Sep 25 10:19 driver.c -rw-rw-r--. 1 wmcquain comporg 154 Sep 25 10:20 rFibonacci.c -rw-rw-r--. 1 wmcquain comporg 104 Sep 25 10:20 rFibonacci.h 1029 wmcquain in ~/2505/notes/T08/v1> OK: the function call matches this declaration; compiler doesn't need to see function definition. The compiler notes that this call "binds" to this declaration. #include <stdio.h> #include <inttypes.h> #include "rFibonacci.h" int main() { for (int i = 0; i < 50; i++) { printf("Fibo(%d) = %"PRIu64"\n", i, rFibonacci(i)); } return 0;

Compilation CentOS> gcc -c -std=c99 -Wall -W driver.c -c switch tells gcc to compile and exit CentOS> gcc -c -std=c99 -Wall -W driver.c CentOS> ls -l total 16 -rw-rw-r--. 1 wmcquain comporg 216 Sep 25 10:19 driver.c -rw-rw-r--. 1 wmcquain comporg 1616 Sep 25 10:24 driver.o -rw-rw-r--. 1 wmcquain comporg 154 Sep 25 10:20 rFibonacci.c -rw-rw-r--. 1 wmcquain comporg 104 Sep 25 10:20 rFibonacci.h If compilation is successful, an object file is created; this is a partial translation of the C source file into machine code.

Linking CentOS> ls -l total 20 -rw-rw-r--. 1 wmcquain comporg 216 Sep 25 10:19 driver.c -rw-rw-r--. 1 wmcquain comporg 1616 Sep 25 10:24 driver.o -rw-rw-r--. 1 wmcquain comporg 154 Sep 25 10:20 rFibonacci.c -rw-rw-r--. 1 wmcquain comporg 104 Sep 25 10:20 rFibonacci.h -rw-rw-r--. 1 wmcquain comporg 1424 Sep 25 10:26 rFibonacci.o CentOS> gcc -o fibo -Wall -W driver.o rFibonacci.o total 32 -rwxrw-r--. 1 wmcquain comporg 8578 Sep 25 10:27 fibo -o switch tells gcc what to call executable can invoke gcc with object files to link them and produce executable

Compilation Errors The compiler will generate error messages if it cannot resolve the references it encounters: #include <stdio.h> #include <stdint.h> #include <inttypes.h> //#include "rFibonacci.h" int main() { for (int i = 0; i < 50; i++) { printf("Fibo(%d) = %"PRIu64"\n", i, rFibonacci(i)); . . . Omit this include directive and the compiler cannot find a declaration that matches the call to rFibonacci(). CentOS> gcc -c -std=c99 -Wall -W driver.c driver.c: In function ‘main’: driver.c:9:7: warning: implicit declaration of function ‘rFibonacci’ [-Wimplicit-function-declaration] printf("Fibo(%d) = %"PRIu64"\n", i, rFibonacci(i)); ^ driver.c:9:7: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘int’ [-Wformat=]

Linker Errors The linker may also produce error messages: Based on Chapter 1 in C++ for Java Programmers by Weiss The linker may also produce error messages: #ifndef RFIBONACCI_H #define RFIBONACCI_H #include <stdint.h> uint64_t rFibonacci(uint64_t n); #endif #include <stdio.h> #include <stdint.h> #include "rFibonacci.h" int main() { for (int i = 0; i < 50; i++) { printf("Fibo(%d) = %lld\n", i, rFibonacci(i)); } return 0; OK Now, linker cannot find a definition (implementation) that matches the function declaration the compiler matched the call to… that's an error. #include "rFibonacci.h" uint64_t Fibonacci(uint64_t n) { if ( n < 2 ) return 1; return rFibonacci(n - 1) + rFibonacci(n - 2); }

Linker Errors Unfortunately, linker error messages are less direct than compiler error messages: CentOS> gcc -o driver -std=c99 -Wall -W driver.c rFibonacci.c /tmp/ccHhmn0D.o: In function `main': driver.c:(.text+0x1a): undefined reference to `rFibonacci' /tmp/ccYcsMDA.o: In function `Fibonacci': rFibonacci.c:(.text+0x27): undefined reference to `rFibonacci' rFibonacci.c:(.text+0x3a): undefined reference to `rFibonacci' collect2: error: ld returned 1 exit status The message does not refer to a specific line of source code. But, it does name a specific function and it implies there's a difference between the declaration of that function and the definition (implementation) of that function.