Institut für Informatik D Augsburg

Similar documents
(6-1) Basics of a Queue. Instructor - Andrew S. O Fallon CptS 122 (September 26, 2018) Washington State University

Introduction to Programming in C Department of Computer Science and Engineering

(2-1) Data Structures & The Basics of a Linked List I. Instructor - Andrew S. O Fallon CptS 122 (August 27, 2018) Washington State University

An implementation model of rendezvous communication

Introduction to Programming in C Department of Computer Science and Engineering

15 212: Principles of Programming. Some Notes on Induction

Functional Programming. Pure Functional Programming

Safely Extending Procedure Types to Allow Nested Procedures as Values 1

Binary Tree Node Relationships. Binary Trees. Quick Application: Expression Trees. Traversals

Binary Trees. For example: Jargon: General Binary Trees. root node. level: internal node. edge. leaf node. Data Structures & File Management

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

2. List Implementations (a) Class Templates (b) Contiguous (c) Simply Linked (d) Simply Linked with Position Pointer (e) Doubly Linked

CS 241 Data Organization Binary Trees

CS558 Programming Languages Winter 2018 Lecture 4a. Andrew Tolmach Portland State University

Functional Languages. Hwansoo Han

Scribe: Virginia Williams, Sam Kim (2016), Mary Wootters (2017) Date: May 22, 2017

Lab 4 - Linked Lists

Introduction to Linked Lists

Programming in C. Lecture 5: Aliasing, Graphs, and Deallocation. Dr Neel Krishnaswami. Michaelmas Term University of Cambridge

Chapter 4: Trees. 4.2 For node B :

6.001 Notes: Section 8.1

A graphical user interface for service adaptation

Lecture 3: Recursion; Structural Induction

FORTH SEMESTER DIPLOMA EXAMINATION IN ENGINEERING/ TECHNOLIGY- OCTOBER, 2012 DATA STRUCTURE

The Design of Core C++ (Notes)

Single-pass Static Semantic Check for Efficient Translation in YAPL

Lists. Readings: HtDP, sections 9 and 10. Avoid 10.3 (uses draw.ss). CS 135 Winter : Lists 1

Variables. Substitution

Data Structures. Alice E. Fischer. Lecture 4, Fall Alice E. Fischer Data Structures L4... 1/19 Lecture 4, Fall / 19

Lecture Notes on Memory Management

CS558 Programming Languages

Functional Programming Languages (FPL)

Functional Programming. Big Picture. Design of Programming Languages

ENEE 150: Intermediate Programming Concepts for Engineers Spring 2018 Handout #27. Midterm #2 Review

Topic 7: Algebraic Data Types

CS61 Section Notes. Section 5 (Fall 2011) Topics to be covered Common Memory Errors Dynamic Memory Allocation Assignment 3: Malloc

Lecture Notes on Binary Search Trees

Evolving Algebras and Partial Evaluation

A Progressive Approach to Recursion

6.001 Notes: Section 6.1

Programming Languages Lecture 14: Sum, Product, Recursive Types

INTRODUCTION. Objective: - Algorithms - Techniques - Analysis. Algorithms:

Lecture Notes on Data Representation

Programming Languages

CSE 250 Final Exam. Fall 2013 Time: 3 hours. Dec 11, No electronic devices of any kind. You can open your textbook and notes

Binary Trees (and Big O notation)

Advanced Programming. Lists. A list is a data structure based on usage of pointers and dynamic allocation of memory.

Heap Arrays and Linked Lists. Steven R. Bagley

Handout 9: Imperative Programs and State

LECTURE 16. Functional Programming

(3-2) Basics of a Stack. Instructor - Andrew S. O Fallon CptS 122 (January 26, 2018) Washington State University

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #34. Function with pointer Argument

C LANGUAGE AND ITS DIFFERENT TYPES OF FUNCTIONS

Linked Lists in C and C++

Unit.9 Integer Programming

Trees. CS 5010 Program Design Paradigms Bootcamp Lesson 5.1

Lecture 4: Elementary Data Structures Steven Skiena

Implementing Software Connectors through First-Class Methods

6.001 Notes: Section 4.1

CMSC 330: Organization of Programming Languages

Imperative Programming Languages (IPL)

Advanced Programming Handout 6. Purely Functional Data Structures: A Case Study in Functional Programming

More Lambda Calculus and Intro to Type Systems

Program Calculus Calculational Programming

Semantics of COW. July Alex van Oostenrijk and Martijn van Beek

CS 125 Section #4 RAMs and TMs 9/27/16

Chapter 3: Propositional Languages

Lecture Notes on Binary Search Trees

Equations for Asynchronous Message Passing

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

1 Introduction. Martin Böhme Bodo Manthey

CS611 Lecture 33 Equirecursive types & Recursive domain equations November 19, 2001

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #44. Multidimensional Array and pointers

1 Dynamic Memory continued: Memory Leaks

Reasoning About Imperative Programs. COS 441 Slides 10

More Lambda Calculus and Intro to Type Systems

Lab 5 - Linked Lists Git Tag: Lab5Submission

Lecture 2: SML Basics

Chapter 11 :: Functional Languages

Constraints in Feature Algebra

The Inverse of a Schema Mapping

Lecture Notes on Interfaces

ITI Introduction to Computing II

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

CS 242. Fundamentals. Reading: See last slide

CS558 Programming Languages. Winter 2013 Lecture 3

A Propagation Engine for GCC

Programming Languages Lecture 15: Recursive Types & Subtyping

MULTIMEDIA COLLEGE JALAN GURNEY KIRI KUALA LUMPUR

BBM 201 DATA STRUCTURES

Programming Assignment #4 Binary Trees in C++

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

CSc 520 Principles of Programming Languages

P Is Not Equal to NP. ScholarlyCommons. University of Pennsylvania. Jon Freeman University of Pennsylvania. October 1989

Chapter 7:: Data Types. Mid-Term Test. Mid-Term Test (cont.) Administrative Notes

Midterm Review. CS 211 Fall 2018

PART ONE Fundamentals of Compilation

CS 161 Computer Security

CS3110 Spring 2017 Lecture 12: DRAFT: Constructive Real Numbers continued

Transcription:

Universität Augsburg Safer Ways to Pointer Manipulation Bernhard Möller Report 2000-4 Mai 2000 Institut für Informatik D-86135 Augsburg

Copyright c Bernhard Möller Institut für Informatik Universität Augsburg D 86135 Augsburg, Germany http://www.informatik.uni-augsburg.de all rights reserved

Safer Ways to Pointer Manipulation Bernhard Möller Institut für Informatik, Universität Augsburg D-86154 Augsburg, Germany e-mail: moeller@informatik.uni-augsburg.de Abstract. We present a technique for passing in a safe way from high-level specifications of algorithms on pointer structures in a semi-functional style to efficient low-level implementations involving address calculations. 1 Introduction This article was motivated by an experience I had while teaching a course on the programming language C [2]. I was trying to write down an algorithm for deleting an element from a singly linked list; this algorithm should not involve trailing auxiliary pointers and the like, but rather work on a single address variable. I failed several times in formulating this algorithm straightforwardly, always somehow mixing up the levels of dereferencing and the like. So I thought of more systematic ways of constructing such an algorithm and remembered my transformational background [1]. Now I first wrote down a simple recursive specification in a semi-functional style, passed to a corresponding procedure and applied the standard technique for recursion removal. The whole thing took less than ten minutes, and I was left with a very nice and correct algorithm of the desired characteristics. I think that this way of proceeding applies to a large class of pointer algorithms and therefore I want to report on it. 2 A General Transformation Scheme We start with the well-known transition from a tail-recursive procedure to one with a loop in its body. Suppose procedure p is defined as void p (type x) { if (cond) p(exp) ; else stat ; 1

where type is some type that does not start with *, cond is an expression of type int, exp is an expression of type type and stat is a statement. Then the definition of p can equivalently be replaced by void p (type x) { while (cond) x = exp ; stat ; For the case of a star type somewhat more care has to be taken to capture side effects on the variables whose addresses are passed as parameters. Here the recursive version void p (type *x) { if (cond) p(exp) ; else stat ; is equivalent to void p (type *y) { type *x = y ; while (cond) x = exp ; stat ; These rules generalize in a straightforward way to the case of several parameters if we use a feature which is not part of official C, viz. a collective assignment of the form (x 1,..., x n ) = (exp 1,..., exp n ). Its semantics is that the tuple of expressions on the right hand side is evaluated in arbitrary order and the resulting values are assigned simultaneously to the variables on the left hand side. No variable may occur twice in the left hand side tuple. To remove this construct, one has to sequentialize the assignments involved which usually requires auxiliary variables. This is a spot of frequent error in attempts to write down algorithms straightforwardly. Therefore we prefer this intermediate step which allows us to avoid such errors by using the standard knowledge about the treatment of collective assignments. 2

3 Singly Linked Lists We now want to exemplify the use of the above rule in the development of a function for deleting an element from a singly linked list. The data type for lists is defined by typedef struct lis { int item ; lis *next ; listel, *list ; Of course, int might be replaced by any other type. Two basic operations on lists are the emptiness test int isempty (list l) { return (l == NULL) ; and adding a new record to the beginning of a list list prefix (int x, list l) { list new = (list) malloc(sizeof(listel)); new->item = x; new->next = l; return new; Here, we have omitted the test for success of the call to malloc. We now give a simple recursive formulation of a function that deletes the first occurrence, if any, of an element x from a list l: list delete (int x, list l) { if (isempty(l)) return l ; else if (l->item == x) return l->next ; else { l->next = delete(x,l->next) ; return l ; We now head for an iterative version. The basic idea is to pass to a tail-recursive pure procedure and subsequently to apply our scheme for transition to loop form. We thus introduce the following procedure which overwrites a list variable with the result of the delete operation: { *l = delete(x, *l) ; 3

This procedure is indirectly recursive through the call to delete. To obtain a directly recursive version we use the unfold/simplify/fold transformation strategy (see e.g. [5]). First we unfold, i.e., substitute the body of delete for its call, replacing the formal parameters x and l by the actual parameters x and *l and, at the same time, distribute the assignment to *l into the branches of the conditional statements: void pdelete (int x, list *l) { if (isempty(*l)) *l = *l ; else if ((*l)->item == x) else { (*l)->next = delete(x,(*l)->next) ; *l = *l ; Next, we remove the trivial assignments *l = *l. To prepare the use of our transformation scheme we moreover reorganize the conditional, exploiting the properties of the logical connectives && and!. This yields { if (!isempty(*l) && ((*l)->item!= x)) (*l)->next = delete(x,(*l)->next) ; else if (!isempty(*l)) The assignment with the call to delete has almost the shape of the body of pdelete; only the level of dereferencing is not right. To prepare folding, i.e., replacement of a statement by a suitable call to a procedure, we therefore have to adjust this so that we obtain a statement of the form *m = delete(y,*m) for suitable m,y. For y we can use x. To find m we use the fact that in C for arbitrary address-valued expression exp the expressions exp and *&exp are equivalent and obtain { if (!isempty(*l) && ((*l)->item!= x)) *&((*l)->next) = delete(x,*&((*l)->next)) ; else if (!isempty(*l)) 4

so that we can take &((*l)->next) for m. We fold the then-branch into a (recursive) call of pdelete with the actual parameter &((*l)->next)) instead of l: { if (!isempty(*l) && ((*l)->item!= x)) pdelete(x, &((*l)->next)) ; else if (!isempty(*l)) This recursion even is a tail recursion. Hence we may now apply our rule for passing to a loop and obtain { while (!isempty(*l) && ((*l)->item!= x)) (x, l) = (x, &((*l)->next)) ; if (!isempty(*l)) Here the collective assignment can be eliminated without introduction of an auxiliary variable, since the assignment to x is trivial anyway and can simply be omitted. This leads to our final version { while (!isempty(*l) && ((*l)->item!= x)) l = &((*l)->next) ; if (!isempty(*l)) It should be noted here that a corresponding version in standard Pascal or Modula does not exist, since these languages do not allow variables of type var var type for addresses of variables. There one has to keep the recursive version which simulates such variables by passing parameters of type var type (see e.g. [6] for the case of a deletion algorithm on binary search trees). 4 Conclusion We hope to have demonstrated that there is a systematic way of passing from simple and clear high-level specifications of algorithms on pointer structures to efficient versions which are much harder to understand and, more importantly, to get right. It may be argued that the proceeding here has not been completely formal so that there still is no complete correctness proof of the final algorithm. 5

However, the approach could fully be formalized using the pointer algebra introduced in [4, 3]. Acknowledgements. I am grateful to T. Ehm, M. Russling, S. Holland and, in particular, G. Wilhelms for valuable comments on draft versions of this paper. References [1] F.L. Bauer, B. Möller, H. Partsch, P. Pepper: Formal program construction by transformations Computer-aided, Intuition-guided Programming. IEEE Transactions on Software Engineering 15, 165 180 (1989) [2] B.W. Kernighan, D.M. Ritchie: Programming in C. Second Edition, ANSI C. Englewood Cliffs, N.J.: Prentice-Hall 1988 [3] B. Möller: Development of graph and pointer algorithms. In B. Möller, H.A. Partsch, S.A. Schuman (eds.): Formal program development. Lecture Notes in Computer Science 755. Berlin: Springer 1993, 123 160 [4] B. Möller: Towards pointer algebra. Science of Computer Programming 21, 57 90 (1993) [5] H.A. Partsch: Specification and transformation of programs A formal approach to software development. Berlin: Springer 1990 [6] N. Wirth: Algorithms and data structures. Englewood Cliffs, N.J.: Prentice- Hall 1986 6