Control Flow. Stephen A. Edwards. Fall Columbia University

Similar documents
int foo() { x += 5; return x; } int a = foo() + x + foo(); Side-effects GCC sets a=25. int x = 0; int foo() { x += 5; return x; }

Ordering Within Expressions. Control Flow. Side-effects. Side-effects. Order of Evaluation. Misbehaving Floating-Point Numbers.

Control Flow COMS W4115. Prof. Stephen A. Edwards Fall 2006 Columbia University Department of Computer Science

LECTURE 18. Control Flow

CSc 520 Principles of Programming Languages. 26 : Control Structures Introduction

Control Structures. Outline. In Text: Chapter 8. Control structures Selection. Iteration. Gotos Guarded statements. One-way Two-way Multi-way

Chapter 6 Control Flow. June 9, 2015

COP4020 Programming Languages. Control Flow Prof. Robert van Engelen

Page # Expression Evaluation: Outline. CSCI: 4500/6500 Programming Languages. Expression Evaluation: Precedence

Chapter 7. - FORTRAN I control statements were based directly on IBM 704 hardware

! Non-determinacy (unspecified order) Maria Hybinette, UGA 2. 1 Landin adding sugar to a language to make it easier to read (for humans)

Statement level control structures

Lecture 15: Iteration and Recursion

Programming Languages Third Edition. Chapter 9 Control I Expressions and Statements

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Names, Scope, and Bindings

LECTURE 17. Expressions and Assignment

Names, Scope, and Types

Control Flow. CSE 307 Principles of Programming Languages Stony Brook University

CMPT 379 Compilers. Anoop Sarkar. 11/13/07 1. TAC: Intermediate Representation. Language + Machine Independent TAC

Chapter 8. Statement-Level Control Structures

Chapter 8. Statement-Level Control Structures

NOTE: Answer ANY FOUR of the following 6 sections:

Expressions vs statements

Programming Language Pragmatics

CSE 452: Programming Languages. Outline of Today s Lecture. Expressions. Expressions and Control Flow

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

C Language Part 2 Digital Computer Concept and Practice Copyright 2012 by Jaejin Lee

Names, Scope, and Bindings

Chapter 8. Statement-Level Control Structures

G Programming Languages - Fall 2012

Subprograms. Akim D le Étienne Renault Roland Levillain EPITA École Pour l Informatique et les Techniques Avancées

Compilers CS S-05 Semantic Analysis

COMP-520 GoLite Tutorial

Ch. 7: Control Structures

System Software Assignment 1 Runtime Support for Procedures

SE352b: Roadmap. SE352b Software Engineering Design Tools. W3: Programming Paradigms

Object Code (Machine Code) Dr. D. M. Akbar Hussain Department of Software Engineering & Media Technology. Three Address Code

Lecture 9: Control Flow

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Names, Scope, and Bindings

Names, Scope, and Bindings

1 Lexical Considerations

G Programming Languages - Fall 2012

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Review for the Final

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

Procedures and Stacks

Functional Programming. Big Picture. Design of Programming Languages

Imperative Programming Languages (IPL)

Chapter 7 Control I Expressions and Statements

Weeks 6&7: Procedures and Parameter Passing

CSC 533: Organization of Programming Languages. Spring 2005

An Introduction to Scheme

Flow of Control Execution Sequence

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

Chapter 11 Introduction to Programming in C

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Intermediate Representa.on

The C Language COMS W Prof. Stephen A. Edwards Fall 2002 Columbia University Department of Computer Science

CISC-124. Casting. // this would fail because we can t assign a double value to an int // variable

Chapter 8. Statement-Level Control Structures ISBN

Programming Languages

Iterative Statements. Iterative Statements: Examples. Counter-Controlled Loops. ICOM 4036 Programming Languages Statement-Level Control Structure

CIT Week13 Lecture

4. Functions. March 10, 2010

Introduction to Object-Oriented Programming

CS64 Week 5 Lecture 1. Kyle Dewey

Review of the C Programming Language

Abstract Syntax Trees

CS323 Lecture: Control Structures last revised 3/4/09

MIDTERM EXAMINATION - CS130 - Spring 2003

Implementing Actions

CSE 374 Programming Concepts & Tools

Intel x86 Jump Instructions. Part 5. JMP address. Operations: Program Flow Control. Operations: Program Flow Control.

Intermediate Code Generation

Reading Assignment. Lazy Evaluation

Programmiersprachen (Programming Languages)

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

Principle of Complier Design Prof. Y. N. Srikant Department of Computer Science and Automation Indian Institute of Science, Bangalore

General Concepts. Abstraction Computational Paradigms Implementation Application Domains Influence on Success Influences on Design

Sequence structure. The computer executes java statements one after the other in the order in which they are written. Total = total +grade;

CMPS 12A - Winter 2002 Final Exam A March 16, Name: ID:

CSE 3302 Programming Languages Lecture 5: Control

Test 1 Summer 2014 Multiple Choice. Write your answer to the LEFT of each problem. 5 points each 1. Preprocessor macros are associated with: A. C B.

Chapter 8 Statement-Level Control Structures

Language Design COMS W4115. Prof. Stephen A. Edwards Fall 2006 Columbia University Department of Computer Science

Loops. CSE 114, Computer Science 1 Stony Brook University

Intel x86 Jump Instructions. Part 5. JMP address. Operations: Program Flow Control. Operations: Program Flow Control.

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

LECTURE 1. Overview and History

Assembly Language: Function Calls

Parameters. Chapter Eighteen Modern Programming Languages, 2nd ed. 1

Loops. When to Use Loops

CMSC330 Fall 2013 Practice Problems 6 Solutions

Functions. x y z. f (x, y, z) Take in input arguments (zero or more) Perform some computation - May have side-effects (such as drawing)

Implementing Coroutines with call/cc. Producer/Consumer using Coroutines

2/20/2018. Chapter 6:: Control Flow. control flow or ordering. basic categories for control flow (cont.): basic categories for control flow:

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

Transcription:

Control Flow Stephen A. Edwards Columbia University Fall 2013

Control Flow Time is Nature s way of preventing everything from happening at once. Scott identifies seven manifestations of this: 1. Sequencing foo(); bar(); 2. Selection if (a) foo(); 3. Iteration while (i<10) foo(i); 4. Procedures foo(10,20); 5. Recursion foo(int i) { foo(i-1); 6. Concurrency foo() bar() 7. Nondeterminism do a -> foo(); [] b -> bar();

Ordering Within Expressions What code does a compiler generate for a = b + c + d; Most likely something like tmp = b + c; a = tmp + d; (Assumes left-to-right evaluation of expressions.)

Order of Evaluation Why would you care? Expression evaluation can have side-effects. Floating-point numbers don t behave like numbers.

Side-effects int x = 0; int foo() { x += 5; return x; int bar() { int a = foo() + x + foo(); return a; What does bar() return?

Side-effects int x = 0; int foo() { x += 5; return x; int bar() { int a = foo() + x + foo(); return a; What does bar() return? GCC returned 25. Sun s C compiler returned 20. C says expression evaluation order is implementation-dependent.

Side-effects Java prescribes left-to-right evaluation. class Foo { static int x; static int foo() { x += 5; return x; public static void main(string args[]) { int a = foo() + x + foo(); System.out.println(a); Always prints 20.

Number Behavior Basic number axioms: a + x = a if and only if x = 0 Additive identity (a + b) + c = a + (b + c) Associative a(b + c) = ab + ac Distributive

Misbehaving Floating-Point Numbers 1e20 + 1e-20 = 1e20 1e-20 1e20 (1 + 9e-7) + 9e-7 1 + (9e-7 + 9e-7) 9e-7 1, so it is discarded, however, 1.8e-6 is large enough 1.00001(1.000001 1) 1.00001 1.000001 1.00001 1 1.00001 1.000001 = 1.00001100001 requires too much intermediate precision.

What s Going On? Floating-point numbers are represented using an exponent/significand format: 1 10000001 {{ 01100000000000000000000 {{ 8-bit exponent 23-bit significand = 1.011 2 2 129 127 = 1.375 4 = 5.5. What to remember: 1363.4568 {{ 46353963456293 {{ represented rounded

What s Going On? Results are often rounded: 1.00001000000 1.00000100000 1.00001100001 {{ rounded When b c, b + c is small, so ab + ac a(b + c) because precision is lost when ab is calculated. Moral: Be aware of floating-point number properties when writing complex expressions.

Short-Circuit Evaluation When you write if (disaster_could_happen) avoid_it(); else cause_a_disaster(); cause_a_disaster() is not called when disaster_could_happen is true. The if statement evaluates its bodies lazily: only when necessary. The section operator? : does this, too. cost = disaster_possible? avoid_it() : cause_it();

Logical Operators In Java and C, Boolean logical operators short-circuit to provide this facility: if (disaster_possible case_it()) {... cause_it() only called if disaster_possible is false. The && operator does the same thing. Useful when a later test could cause an error: int a[10]; if (i => 0 && i < 10 && a[i] == 0) {...

Unstructured Control-Flow Assembly languages usually provide three types of instructions: Pass control to next instruction: add, sub, mov, cmp Pass control to another instruction: jmp rts Conditionally pass control next or elsewhere: beq bne blt

Unstructured Control-Flow B: BEQ A JMP C A: C: D: BEQ D BEQ B BNE B RTS

Structured Control-Flow The object-oriented languages of the 1960s and 70s. Structured programming replaces the evil goto with structured (nested) constructs such as for while break return continue do.. while if.. then.. else

Gotos vs. Structured Programming A typical use of a goto is building a loop. In BASIC: 10 PRINT I 20 I = I + 1 30 IF I < 10 GOTO 10 A cleaner version in C using structured control flow: do { printf("%d\n", i); i = i + 1; while ( i < 10 ) An even better version for (i = 0 ; i < 10 ; i++) printf("%d\n", i);

Gotos vs. Structured Programming Break and continue leave loops prematurely: for ( i = 0 ; i < 10 ; i++ ) { if ( i == 5 ) continue; if ( i == 8 ) break; printf("%d\n", i); i = 0; Again: if (!(i < 10)) goto Break; if ( i == 5 ) goto Continue; if ( i == 8 ) goto Break; printf("%d\n", i); Continue: i++; goto Again; Break:

Escaping from Loops Java allows you to escape from labeled loops: a: for (int i = 0 ; i < 10 ; i++) for ( int j = 0 ; j < 10 ; j++) { System.out.println(i + "," + j); if (i == 2 && j == 8) continue a; if (i == 8 && j == 4) break a;

Gotos vs. Structured Programming Pascal has no return statement for escaping from functions/procedures early, so goto was necessary: procedure consume_line(var line : string); begin if line[i] = % then goto 100; (*... *) 100: end In C and many others, return does this for you: void consume_line(char *line) { if (line[0] == % ) return;

Loops A modern processor can execute something like 1 billion instructions/second. How many instructions are there in a typical program? Perhaps a million. Why do programs take more than 1ms to run? Answer: loops This insight is critical for optimization: only bother optimizing the loops since everything else is of vanishing importance.

Enumeration-Controlled Loops in FORTRAN do 10 i = 1, 10, 2... 10: continue Executes body of the loop with i=1, 3, 5,..., 9 Tricky things: What happens if the body changes the value of i? What happens if gotos jump into or out of the loop? What is the value of i upon exit? What happens if the upper bound is less than the lower one?

Changing Loop Indices Most languages prohibit changing the index within a loop. (Algol 68, Pascal, Ada, FORTRAN 77 and 90, Modula-3) But C, C++, and Java allow it. Why would a language bother to restrict this?

Empty Bounds In FORTRAN, the body of this loop is executed once: do 10 i = 10, 1, 1... 10: continue for i = 10 to 1 by 1 Test is done after the body. Modern languages place the test before the loop. Does the right thing when the bounds are empty. Slightly less efficient (one extra test).

Scope of Loop Index What happens to the loop index when the loop terminates? Index is undefined: FORTRAN IV, Pascal. Index is its last value: FORTRAN 77, Algol 60 Index is just a variable: C, C++, Java Tricky when iterating over subranges. What s next? var c : a.. z ; for c := a to z do begin... end; (* what s c? *)

Scope of Loop Index Originally in C++, a locally-defined index variable s scope extended beyond the loop: for (int i = 0 ; i < 10 ; i++) {... a = a + i; // Was OK: i = 10 here But this is awkward: for (int i = 0 ; i < 10 ; i++) {...... for (int i = 0 ; i < 10 ; i++) // Error: i redeclared

Scope of Loop Index C++ and Java now restrict the scope to the loop body: for (int i = 0 ; i < 10 ; i++ ) { int a = i; // OK... int b = i; // Error: i undefined... for (int i = 0 ; i < 10 ; i++ ) { // OK Rather annoying: broke many old C++ programs. Better for new code.

Algol s Combination Loop for for id := for-list do stmt for-list enumerator (, enumerator )* enumerator expr expr step expr until expr expr while condition Equivalent: for i := 1, 3, 5, 7, 9 do... for i := 1 step 2 until 10 do... for i := 1, i+2 while i < 10 do... Language implicitly steps through enumerators (implicit variable).

Mid-test Loops while true do begin readln(line); if all_blanks(line) then goto 100; consume_line(line); end; 100: In Modula-2: LOOP line := ReadLine; WHEN AllBlanks(line) EXIT; ConsumeLine(line) END;

Multi-way Branching switch (s) { case 1: one(); break; case 2: two(); break; case 3: three(); break; case 4: four(); break; switch (s) { case 1: goto One; case 2: goto Two; case 3: goto Three; case 4: goto Four; goto Break; One: one(); goto Break; Two: two(); goto Break; Three: three(); goto Break; Four: four(); goto Break; Break: Switch sends control to one of the case labels. Break terminates the statement. Really just a multi-way goto:

Implementing multi-way branches switch (s) { case 1: one(); break; case 2: two(); break; case 3: three(); break; case 4: four(); break; Obvious way: if (s == 1) { one(); else if (s == 2) { two(); else if (s == 3) { three(); else if (s == 4) { four(); Reasonable, but we can sometimes do better.

Implementing multi-way branches If the cases are dense, a branch table is more efficient: switch (s) { case 1: one(); break; case 2: two(); break; case 3: three(); break; case 4: four(); break; A branch table written using a GCC extension: /* Array of addresses of labels */ static void *l[] = { &&L1, &&L2, &&L3, &&L4 ; if (s >= 1 && s <= 4) goto *l[s-1]; goto Break; L1: one(); goto Break; L2: two(); goto Break; L3: three(); goto Break; L4: four(); goto Break; Break:

Recursion and Iteration To compute 10 i=0 f (i ) in C, the most obvious technique is iteration: double total = 0; for ( i = 0 ; i <= 10 ; i++ ) total += f(i);

Recursion and Iteration To compute 10 i=0 f (i ) in C, the most obvious technique is iteration: double total = 0; for ( i = 0 ; i <= 10 ; i++ ) total += f(i); But this can also be defined recursively double sum(int i, double acc) { if (i <= 10) return sum(i+1, acc + f(i)); else return acc; sum(0, 0.0);

Tail-Recursion and Iteration int gcd(int a, int b) { if ( a==b ) return a; else if ( a > b ) return gcd(a-b,b); else return gcd(a,b-a); Notice: no computation follows any recursive calls. Stack is not necessary: all variables dead after the call. Local variable space can be reused. Trivial since the collection of variables is the same. Works in O Caml, too let rec gcd a b = if a = b then a else if a > b then gcd (a - b) b else gcd a (b - a)

Tail-Recursion and Iteration int gcd(int a, int b) { if ( a==b ) return a; else if ( a > b ) return gcd(a-b,b); else return gcd(a,b-a); Can be rewritten into: int gcd(int a, int b) { start: if ( a==b ) return a; else if ( a > b ) a = a-b; goto start; else b = b-a; goto start; Good compilers, especially those for functional languages, identify and optimize tail recursive functions. Less common for imperative languages, but gcc -O was able to handle this example.

Applicative- and Normal-Order Evaluation int p(int i) { printf("%d ", i); return i; void q(int a, int b, int c) { int total = a; printf("%d ", b); total += c; q( p(1), 2, p(3) ); What does this print?

Applicative- and Normal-Order Evaluation int p(int i) { printf("%d ", i); return i; void q(int a, int b, int c) { int total = a; printf("%d ", b); total += c; q( p(1), 2, p(3) ); What does this print? Applicative: arguments evaluated before function is called. Result: 1 3 2 Normal: arguments evaluated when used. Result: 1 2 3

Applicative- vs. and Normal-Order Most languages use applicative order. Macro-like languages often use normal order. #define p(x) (printf("%d ",x), x) #define q(a,b,c) total = (a), \ printf("%d ", (b)), \ total += (c) q( p(1), 2, p(3) ); Prints 1 2 3. Some functional languages also use normal order evaluation to avoid doing work. Lazy Evaluation

Argument Order Evaluation C does not define argument evaluation order: int p(int i) { printf("%d ", i); return i; int q(int a, int b, int c) { q( p(1), p(2), p(3) ); Might print 1 2 3, 3 2 1, or something else. This is an example of nondeterminism.

Nondeterminism Nondeterminism is not the same as random: Compiler usually chooses an order when generating code. Optimization, exact expressions, or run-time values may affect behavior. Bottom line: don t know what code will do, but often know set of possibilities. int p(int i) { printf("%d ", i); return i; int q(int a, int b, int c) { q( p(1), p(2), p(3) ); Will not print 5 6 7. It will print one of 1 2 3, 1 3 2, 2 1 3, 2 3 1, 3 1 2, 3 2 1

Nondeterminism Nondeterminism lurks in most languages in one form or another. Especially prevelant in concurrent languages. Sometimes it s convenient, though: if a >= b -> max := a [] b >= a -> max := b fi Nondeterministic (irrelevant) choice when a=b. Often want to avoid it, however.