1). position or keyword/name 2). Pass-by-value: * Mode: in-mode * Transfer: physical move; copy + Won't affect actual parameter if formal changes + No transfer from called procedure - Copying the value can be expensive Pass-by-result: * Mode: out-mode * Transfer: physical move + No transfer to called procedure - Copying the value can be expensive Pass-by-reference: * Mode: in-out mode * Transfer: access path (an address) + Time and space efficient - Access is slower (indirection) - Unsafe - Aliasing 3). Procedure: step of an algorithm Function: semantically modeled as mathematical functions. No side effects Closures: subprograms which capture a referencing environment Coroutines: functions or procedures which may be re-entrant (have multiple entry points) Subroutine: a function or a procedure 4). #include #include #include #include void byRef(std::vector& a) { for (auto& v : a) { v = std::distance(&a[0], &v); } } std::vector byVal(std::vector a) { for (auto& v : a) { v = std::distance(&a[0], &v); } return a; } int main() { int N; std::cin >> N; std::vector val(N); std::vector ref(N); auto start = std::chrono::steady_clock::now(); for (int i = 0; i < 10; ++i) { byRef(ref); } auto stop = std::chrono::steady_clock::now(); std::cout << "By reference: " << std::chrono::duration(stop - start).count() << '\n'; start = std::chrono::steady_clock::now(); for (int i = 0; i < 10; ++i) { auto result = byVal(val); } stop = std::chrono::steady_clock::now(); std::cout << "By value: " << std::chrono::duration(stop - start).count() << '\n'; std::cout << "Same? " << ((val == ref) ? "true" : "false") << '\n'; return 0; } OUTPUT: By reference: 7008.08 By value: 13865.1 Same? false 5). Activation record -- format/layout of the non-code part of an executing subprogram Activation record instance -- concrete example/use of an activation record (including specific links, local variables, and parameters) 6). Deep Access: non-local references are found by searching the dynamic chain. All ARIs must also store their variable names Shallow Access: all locals are stored in a central place/repository where there exists a stack for each variable name. The stacks are updated as subprograms are executed and returned 7. +---------+ | bigsub |<-+-+ +---------+ | | | | +---------+ | | | a |<-|-|-+-+-+ +---------+ | | | | | | static |>-+ | | | | | dynamic |>---+ | | | +---------+ | | | | | | +---------+ | | | | c |<-----|-|-|-+ +---------+ | | | | | static |>-----+ | | | | dynamic |>-------+ | | +---------+ | | | | +---------+ | | | b | | | +---------+ | | | static |>---------+ | | dynamic |>-----------+ +---------+ 8. variable (stack "grows" to the right) | v e | main f | main g | main a | fun1 d | fun3 b | fun2 c | fun2 In this example, there is no "stacking" 9. a. The dynamic link is referred to as the old "base pointer". Lines 2 and 18 push the old base pointer onto the stack. b. The activation record is done in two parts: for parameters, they exist before the dynamic link and local variable declaration, so it depends on the number of parameters. In practice, the base pointer (ebp) refers to the center of the activation record: c. they are stored at the "top" of an activation record. They have negative offsets compared to the base pointer d. they are stored at the "bottom" of an activation record. They have positive offsets compared to the base pointer e. They are pushed and popped onto the stack with the call and ret instructions BONUS: here's a complete ARI for x86: paramN ... param2 (negative offsets from ebp) param1 return address (pushed/popped with call / ret) dynamic link (push/pop ebp) <<<<<< Base Pointer local1 local2 (positive offsets from ebp) ... localN 10. exception: any unusual event that may require special processing exception handler: the part of code which processes exceptions raising exception: when an unusual event occurs and is brought forth to be dealt with continuation: control *continues* to the first statement after the exception handler code after a handler completes its execution finalization: the part of code which will be run regardless of an exception occurring or not built-in exception: one predefined by the language 11. * Error detection is difficult code to write * Can clutter the program with tedious checks * Encourages programmers to consider all possible errors * Exception propagation allow reuse and redefinition of exceptions - Specifically, internal errors can be made more readable depending on the context 12. Ensures execution of code block regardless of exceptional control flow 13. Array bounds checking is expensive and would not provide a performance benefit expected of a close-to-hardware-type language.