generic pointers generic data structures
play

Generic Pointers Generic Data Structures 1 /************ - PowerPoint PPT Presentation

Generic Pointers Generic Data Structures 1 /************ Implementation ***********/ Stacks typedef struct list_node list; struct list_node { string data; list* next; }; We defined stacks of strings typedef struct stack_header stack;


  1. Generic Pointers

  2. Generic Data Structures 1

  3. /************ Implementation ***********/ Stacks typedef struct list_node list; struct list_node { string data; list* next; };  We defined stacks of strings typedef struct stack_header stack; …  But, /**************** Interface ****************/ o the code for stacks of ints would be // typedef ______* stack_t; identical except for string changed to int bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ; o the code for stacks of any type would be stack_t stack_new() identical except for string changed to this /*@ensures \result != NULL; @*/ type /*@ensures stack_empty(\result); @*/ ; void push(stack_t S, string x) o … /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; string pop(stack_t S) /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; 2

  4. /************ Implementation ***********/ Stacks typedef struct list_node list; struct list_node { string data; list* next; };  Each time we need a stack for a new typedef struct stack_header stack; element type, we need to make a copy … of the stack library /**************** Interface ****************/ // typedef ______* stack_t;  This is bad o It’s easy to make a mistake bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ; o We need to come up with new names stack_t stack_new()  int_stack_t, int_stack_empty , … /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ;  int_list, int_list_node, is_int_segment , … o If we discover a bug, we need to fix it in void push(stack_t S, string x) /*@requires S != NULL; @*/ every copy of the library /*@ensures !stack_empty(S); @*/ ;  same if we discover a better implementation string pop(stack_t S) /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ;  For a large application, this quickly becomes unmanageable 3

  5. Generic Data Structures  Stacks are intrinsecally generic data structures o They work the same way no matter the type of their elements o They do not modify elements  they only store them in the data structure and give them back  We would like to implement them as a generic library o a single stack implementation that can be used for elements of any type  without copying it over and over  without a proliferation of function and type names o if we find a bug, there is one place where to fix it  if we are told of a better implementation, there is one file to change 4

  6. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data;  Here’s an idea: list* next; o use a generic type name elem in the library }; o let the client define what elem is typedef struct stack_header stack; … /**************** Interface ****************/  We note the type elem is to be defined // typedef ______* stack_t; by the client in the client interface bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ;  The client needs to define what elem stack_t stack_new() actually is in the client definition code /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; void push(stack_t S, elem x) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; elem pop(stack_t S) /******** Client definitions ********/ /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; typedef string elem; 5

  7. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data; Pros: list* next; };  A single library for any kind of stack typedef struct stack_header stack; … o If the client needs a stack of ints in a /**************** Interface ****************/ different application,  simply define elem as int // typedef ______* stack_t; bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ; o If another application stack_t stack_new() requires a different /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; stack type, just define elem appropriately void push(stack_t S, elem x) /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; elem pop(stack_t S) /******** Client definitions ********/ /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; typedef int elem; 6

  8. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data; Cons: list* next; };  Client application has to be split into typedef struct stack_header stack; two files … /***** Client definitions *****/  Client definition file /**************** Interface ****************/ typedef string elem; This is mildly // typedef ______* stack_t;  Rest of the client application /* Client application */ annoying bool stack_empty(stack_t S) int main() { /*@requires S != NULL; @*/ ; … push … pop … o because } stack_t stack_new()  the library needs elem to be defined /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ;  This must occur before the library  the client application needs the types and void push(stack_t S, elem x) /*@requires S != NULL; @*/ functions provided by the library to be defined /*@ensures !stack_empty(S); @*/ ;  This must occur after the library elem pop(stack_t S) /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; 7

  9. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data; list* next; /***** Client definitions *****/ }; Client definitions file client-stack.c0 typedef string elem; typedef struct stack_header stack; … /* Client application */ App. /**************** Interface ****************/ int main() { file main.c0 … push … pop … // typedef ______* stack_t; } bool stack_empty(stack_t S) Linux Terminal /*@requires S != NULL; @*/ ; # cc0 -d client-stack.c0 stack.c0 main.c0 stack_t stack_new() /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; Library void push(stack_t S, elem x) file stack.c0 /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ;  This forces an unnatural compilation elem pop(stack_t S) pattern /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/ ; This is mildly annoying 8

  10. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data; Cons: list* next; };  Client application can contain at most typedef struct stack_header stack; one type of stacks … /**************** Interface ****************/ o no way to have both a stack of strings and // typedef ______* stack_t; a stack of ints in the same application This is a big deal  but we can have multiple stacks of ints bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ; o because there can be only one definition stack_t stack_new() /*@ensures \result != NULL; @*/ for elem /*@ensures stack_empty(\result); @*/ ; void push(stack_t S, elem x) /***** Client definitions *****/ ? /*@requires S != NULL; @*/ /*@ensures !stack_empty(S); @*/ ; typedef string elem; typedef int elem; The compiler won’t elem pop(stack_t S) know which elem /*@requires S != NULL; @*/ to use when /*@requires !stack_empty(S); @*/ ; Compilation error! 9

  11. /************ Client Interface ***********/ // typedef ______ elem; Generic Stacks -- Take 1 /************ Implementation ***********/ typedef struct list_node list; struct list_node { elem data; Summary list* next; }; typedef struct stack_header stack;  Pros: … o A single library for any kind of stacks /**************** Interface ****************/ // typedef ______* stack_t; This is mildly annoying  Cons: bool stack_empty(stack_t S) /*@requires S != NULL; @*/ ; o Client application is split into two files stack_t stack_new()  Unnatural compilation pattern /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/ ; o Client application can contain at most one void push(stack_t S, elem x) /*@requires S != NULL; @*/ type of stacks /*@ensures !stack_empty(S); @*/ ; elem pop(stack_t S) /*@requires S != NULL; @*/ This is a /*@requires !stack_empty(S); @*/ ; big deal 10

  12. Can we do Better?  Not in C0 …  … but the language C1 extends C0 with a mechanism to address these issues 11

  13. C1 12

  14. The language C1  C1 is an extension of C0 o Every C0 program is a C1 program  C1 provides two additional mechanisms o Generic pointers o Function pointers Both help with genericity  Right now, we will only examine generic pointers 13

  15. Running C1 Programs  C1 programs are compiled with cc0 o but C1-only constructs are only allowed in files with a .c1 extension  C0-only code can appear in files with either a .c0 or a .c1 extension  Example Linux Terminal # cc0 -d uba.c0 stack.c1 main.c1 File written File with File that may (or may not) purely in C0 C1 code contain C1 constructs  The coin interpreter does not currently support C1 constructs o no way to experiment with them in coin 14

  16. Generic Pointers 15

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend