190 likes | 324 Views
Review. Creating a Runnable Program. What is the function of the compiler? What is the function of the linker? Java doesn't have a linker. If the "main" class uses other classes, what happens? does javac combine all classes in one class file? does java load the classes? when?
E N D
Creating a Runnable Program • What is the function of the compiler? • What is the function of the linker? • Java doesn't have a linker.If the "main" class uses other classes, what happens? • does javac combine all classes in one class file? • does java load the classes? when? • what does this statement do? Class.forName("com.mysql.jdbc.Driver");
Linker • The linker "resolves" external references, it fills in the missing values in object files. • But, it doesn't check that the names match the expected type! • Example: homework 6A problem 1: /* File 1 */ char *foo; extern double bar; ... printf("%s", foo); printf("%f", bar); /* File 2 */ extern double foo; char* bar = "foo!"; ... printf("%d", foo); printf("%s", bar);
Homework 4 There are two parts to a language: • syntax is the grammar rules for writing (or saying) the language. It describes what are legal expressions. The grammar has 2 parts. • lexical grammar - rules for tokens (words, punctuation, space) • syntactic grammar - rules for statements • What notation is commonly used for these two parts? • semantics describes the meaning of the language • usually given in a manual (in human language) • formal semantics: axiomatic, denotational, and operational semantics • precisely describe effect of language on the computer's "state", can be used to prove program correctness.
Homework 5 Representation of primitive data types: • how big is an int, long, float, double? • what's the largest value you can store in a long? • what format is used to store signed integers? • If you look at a (signed) integer in memory and see: 111111111111111111111111111111111111111111 what value does this represent? • If you look in memory using hexadecimal format and see: 7FFFFFFF is this a positive or negative value? What's the value?
Homework 5 Representation of primitive data types: • floating point numbers are stored as 3 components. What are the 3 components? • the largest float is about 2 x 2126 ( 255 - bias ), so the smallest value should be 1 x 2-127 ( 0 - bias ), but its not! • why is the smallest float 1 x 2-149 ( 1.4E-45 ). Why? • what floating point is returned in these cases, using IEEE standard floating point: • float x = 1.0E20; float result1 = x*x*x*x; • float result2 = 1.0/(x*x*x*x); • double zero = 0.0; double result3 = 1.0/zero; • double result4 = zero * result1; • In Java, how can you test if x (say, "double x") is Infinity? • Test for x is NaN?
Test for Infinity and NaN In Java... double x = ...; if ( x == Double.POSITIVE_INFINITY ) ... if ( Double.isInfinite(x) && x > 0 ) ... if ( x == Double.NEGATIVE_INFINITY ) ... if ( Double.isInfinite(x) && x < 0 ) ... /* for NaN there is no constant. Use function */ if ( Double.isNaN(x) ) ... In C++ use: #include <numeric> numeric_limits<double> dbl; if ( x == dbl.infinity( ) ) ...
3 Memory areas • The memory area allocated for a program's data is divided into 3 areas. What are their names?
3 Memory areas • The memory area allocated for a program's data is divided into 3 areas. What are their names? • Static area • Stack • Heap • How are these three areas used? • What sort of values are placed there? • depends on the language: statically typed languages generally use them as discussed in class • dynamic typed languages (Perl, SmallTalk, Scheme) use the heap for most things
Weird functions • A programmer writes a timer like this: time_t tstart = time(0); // starting time doSomeWork( ); time_t tstop = time(0); // stopping time /* now print when the program started/stopped */ char* start = ctime( tstart ); char* stop = ctime( tstop ); printf("Job started: %s\n", start); printf("Job finished: %s\n", stop); • but both output values are always the same! Why? Job started: Wed Dec 14 2005 13:14:39 PM Job finished: Wed Dec 14 2005 13:14:39 PM
Weird functions: static memory • ctime uses a static buffer to create a string of the formatted time ("Wed Dec 14 ..."). • it returns a pointer to this buffer. • it reuses the same buffer each time it is invoked! Static buffer: char* start = ctime(time1); Tue Dec 13 2005 1:00 AM char* start Wed Dec 14 2005 13:00 PM char* stop = ctime(time2);
Weird functions: why static memory? • Why use static memory for the string buffer? • why not a local (stack automatic) variable? ctime( time_t time ) { char buf[80]; ... return buf; stack: char* time = ctime(time1); ... ... x = fun(10,20,30); ... printf("%s\n", time); Wed Dec 14 2005 13:00:00 PM\n 000000000000010100000000000001010000000000000011110
Weird functions: why static memory? • why not use malloc (heap dynamic) variable? ctime( time_t time ) { char* buf = (char *)malloc(80); ... return buf; heap: char* time; time = ctime(time1); ... time = ctime(time2); ... time = ctime(time3); Wed Dec 14 2005 11:00 AM Wed Dec 14 2005 12:00 AM Wed Dec 14 2005 13:00 PM
Alignment • as described in class, int, float, and double values must usually be aligned on word boundaries (word = 4 bytes) • some CPU require "double" aligned on double word boundaries (8 bytes). • how much space is used by these struct variables? struct one { char c; double d; } x; /* try changing order */ struct two { double d; char c; } y; struct three { char c1; double d1; char c2; double d2; char c3; double d3 } z;
Data type compatibility • each language has rules for compatibility of data types • C++, Java, C#: "widening" conversions allowed; others require a cast and may throw an exception. • what about compatibility of user defined types? double dbl = 3.5; float flt = 1.2F; int nint = 1234567890; long nlng = 12345678901234567890; /* OK */ dbl = flt; dbl = nlng; dbl = nint; flt = nlng; flt = nint; nlng = int; /* Error (but OK in C) */ flt = dbl; nint = nlng; nlng = float; is there a problem here?
Type Compatibility for user types struct A { float x; char c; }; struct B { float x; char c; }; struct C { float z; char c; }; struct D { char c; float x; }; Which of these assignments are allowed? Is the test condition true? int main( ) { struct A a; struct B b; struct C c; struct D d; a.x = 0.5; a.c = 'a'; b = a; // ?? c = a; // ?? d = a; // ?? if (b == a) // true?
Constants • Manifest constant (literal): const int BUFSIZE = 1024; char buf[BUFSIZE]; • Compile time (everything is known): const int BUFSIZE = 8 * 128; • Load time (determined when program is loaded): static final String user = System.getenv("username"); /* java */ • Run-time: int fun(const int n) { const size = n*n; ... } final int width = 400; /* java instance var */
Scope of Names • Categories of scope rules: • lexical(static) scope - scope known by looking at the code. • dynamicscope - follows flow of execution • most languages use lexical scope, but each has its own rules about redefining names in inner scopes. • example of name conflict: #include <math.h> /* hypot is an error in C but not in C++ ! */ float hypot(float x, float y) { return sqrt(x*x + y*y); }
Keeping Track of Names • Compiler (or interpreter) uses a symbol tableto record known names and their attributes (bindings). • For lexical scope, there are two approaches: • a new symbol table for each scope: a stack of symbol tables • a linked list of definitions for each symbol (name), elements of the linked list have scope number • to keep track of active scopes: scope stack • Symbol table is not needed after program is linked, but is usually hidden in the executable code to aid debugging. • To make program smaller or inhibit reverse engineering: strip • C#: "Dotfuscation" pun on "obfuscation" - to make confused or opaque