Você está na página 1de 19

Lecture 14 - Tuesday, 2/25/03

Today
Separate compilation
Name collisions

Reading Assignments For Next Class


Pp. 107-112

Assignments
None outstanding

Spring 2003 CS 403 Class Notes

Page 1

Review: Static vs. Dynamic Scope


int x;
void foo(){
cout << x << endl;
}
void bar(){
int x;
x = 2;
foo()
}

Static scope output: 3


Dynamic scope output: 2
C(++) uses static scope

void main(){
x = 3;
bar();
}

Spring 2003 CS 403 Class Notes

Page 2

Function Visibility
Static vs. dynamic scope: Important because
they resolve global variables
Function visibility: Something of a separate
issue:
What functions can you see from where?

Spring 2003 CS 403 Class Notes

Page 3

Nesting Diagram: Summary of Everything


So Far (assumes static scope)
P1
declaration:x P2

P3

P4
F1

Assume above diagram reflects text order


P4 can call P2
P2 cannot call P4 (comes after)
P2 can call P3, but not F1
F1 can call P2, P4 (recursively), P1 (recursively)
P3 can see the declaration of x in P2
P2 can see its own declaration of x.
P1, P4 and F1 cannot see the declaration of x.
Spring 2003 CS 403 Class Notes

Page 4

Separate Compilation
What happens when you have classes and functions
spread across multiple compilation units?
In file foo.c:
void foo(){.};

In file main.c:
void main(){foo();}

What happens here:


Compile foo.c into foo.o. No problem.
Compile main.c into main.o. Problem no declaration of
foo preceding main.

Spring 2003 CS 403 Class Notes

Page 5

The Classic C Solution


Have foo.h and foo.c:
foo.h: void foo();
foo.c: void foo(){body of function}

foo.c Will still compile as before.


In main.c:
#include foo.h
void main(){foo();}
Compiling main.c now works
Link foo.o, main.o to make final executable
What about doing #include foo.c?
How is this different?
Spring 2003 CS 403 Class Notes

Page 6

Using #include with Classes


Put the interface (declaration) of the class in
the header file:
foo.h:
class foo{
private:
.
public:
int a();
int b();
};

Spring 2003 CS 403 Class Notes

foo.c:
#include foo.h
int foo::a(){

}
int foo::b(){

}
Page 7

Main Function
#include foo.h
void main(){
foo f;
f.a();
f.b();
}

Compile foo.c -> creating foo.o


Compile main.c -> creating main.o
Link the two .o files to create final executable

Spring 2003 CS 403 Class Notes

Page 8

Problem: Redundant Multiple Declarations


foo.h:

main.cpp:

#include <iostream.h>
class foo{

};

#include foo.h
#include <iostream.h>
void main()
.
}

To resolve: Use #ifndef CONSTANT


#define CONSTANT
code to include
#end if
This is typically done in the header file itself
Spring 2003 CS 403 Class Notes

Page 9

C(++) Global Variables With Separate


Compilation
Declaring a variable as extern means that its
actual declaration is unavailable during
compilation
This open issue is resolved on linking
Not particularly good software engineering
practice

Spring 2003 CS 403 Class Notes

Page 10

C(++) Extern Variables


main.c:

foo.c:

void main(){
extern int x;
x = 3;
}

int x;

These are compiled separately and then linked.


If main.c contained #include foo.c as its first line, would
the extern be needed?

Spring 2003 CS 403 Class Notes

Page 11

Separate Compilation: Java

Java source code stored in .java files


Java binary code stored in .class files
Example:
main.java (compiled to main.class)
foo.java (compiled to foo.class)
main is a client of foo.

Compilation:
Compiling foo.java to foo.class is straightforward (no other code files involved).
Compiling main.java to main.class requires that the compiler look for the code
for foo (e.g., to check function calls in terms of type and number of parameters)
Compiler uses the classpath variable (must be set as part of the run-time
environment configuration) to look for foo in this case
Source code for foo is not needed (only the .class file is needed)

Linking normally occurs dynamically:


Using the Java bytecode interpreter (or a browser), run main.class
foo.class is loaded dynamically

Spring 2003 CS 403 Class Notes

Page 12

Comparing the Approaches


C/C++:

File inclusion
More primitive idea
Have to worry about redundant includes
Language really doesnt address the problem directly.
Must separate interface from implementation or you really dont have
separate compilation

Java:
No direct copying as with file inclusion
Dont have to separate interface from implementation to achieve
separate compilation
Less efficient (involves some searching to find server classes)
Less primitive than what happens in C++

Name conflicts: Are a problem with either approach.


Spring 2003 CS 403 Class Notes

Page 13

Name Conflicts

class String

void main(){
String s;
..
}

Spring 2003 CS 403 Class Notes

class String

Frequently, some classes


might show up in multiple
header files.

Page 14

Java Solution
Define packages:
package foo;
public class blah{
public int a(){}
public int c(){}
};
public class ugh{
public int b(){}
public int d(){}
};
Packages may be split over multiple files
If multiple files:
Store all files related to the package in jar file or directory

Spring 2003 CS 403 Class Notes

Page 15

Main Program
Set the classpath to refer to the location of foo
class main {
public static main(){
foo.ugh u = new foo.ugh;
u.a()
}
}

Compile both files and you are ready to go


How this resolves name conflicts:
Use unique names within a package
Names declared in different packages must be qualified
with package name
Spring 2003 CS 403 Class Notes

Page 16

Importing a Package
You can import a package and eliminate the need for
qualified naming, e.g.:
import foo.*; (or import foo.ugh)
class main {
public static main(){
ugh u = new ugh;
u.a()
}
}

This eliminates the whole rationale for packages


(name collisions), but if you are only importing one
package without other external references, it may
simplify your code.
Spring 2003 CS 403 Class Notes

Page 17

Namespaces in C++
Analogous to the package concept in Java:
namespace foo{
class blah{
};
class ugh{
};
}

This requires that classes in foo be referenced by the


namespace qualifier:
foo::blah instead of blah
foo::ugh instead of ugh

You can import a namespace and eliminate the need for the
qualifier, but like in Java, this eliminates the benefit of the
namespace:
using namespace foo;
Spring 2003 CS 403 Class Notes

Page 18

Static vs. Dynamic Linking


Static linking:
Prior to run time, linker combines binary files for separate
components together into a single executable.
This approach used in Visual C++.

Dynamic linking:
Individual binary files for the separate components are
loaded on demand at run-time.
This approach used in Java (JDK).
This approach also used by Microsoft with Dynamic Link
Libraries, which may be implemented in Visual C++.

Spring 2003 CS 403 Class Notes

Page 19

Você também pode gostar