Midterm CS343

Post midterm. Let’s redo the questions to learn from it.

Try to get marks back for:

    1. j) I basically said if the expression is from the Base class and has its derived class exception!
  • Ask clarification for 1. k)
  • I should get a point for 2. d) ii. for mentioning stackful?
  • For 2. e) I mentioned going from coroutine to coroutine, but just didn’t mention resuming it. Try to get a point for it.

1

  • a) i. 1 mark What is the software-engineering problem with the following code.
S;
while(C) {
	// process S data
	S;
}

Code duplication.

  • ii. 4 marks Rewrite the code fragment to eliminate the software-engineering problem.
for(;;) {
	S;
	if(!C) break;
	// process S data
}
  • b) 4 marks Rewrite the following code fragment using only if, labels, and gotos; no else or compound-statement “{}”.
while(C) {
	S;
}

Answer:

Label1:
if(!C) goto Label2;
S;
goto Label 1;
Label2: ;
  • c) 1 mark Why do labelled breaks have good eye-candy?
    • Allow programmer to avoid making mistakes. And if we change the structure and add some control flow, it makes sure that it is still correct.
    • The good eye-candy is the labels at the start of the control structures associated with the labelled break.
  • d) 1 mark What does the term “static” mean in static multi-level exit?
    • static in static multi-level exit means we know where it’s going to exit statically. Not indicated at runtime.
    • The control-structure exit point is known at compile time.
  • e) 1 mark Explain when a flag variable is necessary.
    • When you need to retain and use a variable outside of a block.
    • A flag variable is necessary to retain state from one inner lexical (static) scope to another inner lexical scope.
  • f) 2 marks Give two reasons why is it better to use the stack than the heap for storage allocation?
    • Stack is faster, no need to go through trouble of allocating memory if we use what’s available. And the stack is safer, no memory management required.
    • Stack allocation is cheaper than heap allocation. Stack allocation has implicit deallocation. Stack allocation uses a non-shared refactored because return code checking.
  • g) 1 mark How does modularization fail when refactoring static multi-level exits?
    • When refactoring multi-level exits, modularization fails because if we want to break out the code and do it in another function, it’s possible that it cannot be done since it’s out of bounds and we cannot reach where it wants the program to exit.
    • Label usage cannot be refactored because labels have routine scope.
    • Modularization fails when refactoring static multi-level exits because labels used for multi-level exits are scoped to the specific routine in which they are defined. When attempting to refactor or modularize code that relies on these labels, it’s impossible to carry the label-based exit points over to new modular components, as they are only valid within their original routine scope. This limitation makes it challenging to split such routines into modular, reusable pieces without restructuring the exit logic.
  • h) 2 marks Give an advantage and disadvantage of the return union.
    • I genuinely didn’t know it well but still got my marks by saying: Advantage would be that we have all the information in one place. Easy to implement. Disadvantage of return union would be that it is slow. Because you need to union two things and return it. Takes space.
    • Advantage: return union (mostly) forces return code checking.
    • Disadvantage: return union must be checked at every level of stack unwinding OR the number of alternatives in the union can become large.
  • i) 2 marks What are the two components of a label variable?
    • transfer pointer to a block activation on the stack: this points to the specific activation record (or stack frame) of the block where the label is defined, allowing access to the correct context for execution.
    • transfer point within a block: this identifies the exact location within the block (such as a specific line or statement) where execution should resume or transfer to when the label is used.
    • basically “jump” to a specified location!
  • j) 2 marks Explain the two scenarios where an inherited exception is implicitly truncated, i.e., changed from its derived to base class
    • At the throw when a derived exception is raised using the exception’s base type. (C++ throw truncates but μC++ _Throw does not.) At the catch when a derived exception is caught by value for exception’s base type.
  • k) 2 marks What happens when an exception is reraised?
    • Answer: Reraise terminates the current handler and continues propagation of the caught exception.
    • I guess I didn’t mention that it terminates the current handler and lost 1 mark??
  • l) 2 marks Explain a bound catch-clause.
    • Answer: The catch clause depends on the raised exception and the object raising the exception.
    • Explanation: A bound catch-clause is a catch block in exception handling that not only depends on the type of exception raised but is also contextually bound to the specific object or instance that raised the exception. This means the catch-clause can handle exceptions differently based on both the exception type and the originating object, allowing for more granular and context-specific error handling in complex systems where different objects might need distinct exception responses.
  • m) 1 mark Explain what a sequel and a catch clause have in common.
    • Answer: The sequel and catch clause have static return.
      • both constructs have a defined, predictable type or structure for the values they return.

2

  • a) 2 marks What class of problems does a coroutine handle better than the basic control-flow constructs?
    • Answer: A coroutine handles the class of problems that require state information to be retained between successive calls (e.g. finite-state machine).
    • Deals with switching between different tasks that are trying to accomplish something together, and allows one task to notify/suspend context switch between each other. Don’t need all the flags anymore because we can jump around.
  • b) 3 marks What is special about the first resume of a coroutine?
    • OMG i wanna kill myself. I only mentioned the part where it goes into the main for the first time.
    • Answer: Sets the starter coroutine, creates the coroutine’s stack, and starts the coroutine’s main running on this stack.
  • c) Assume the following code fragment is in a coroutine main to compute the sum of the even and odd digits of a 10-digit number, where each digit is passed to the coroutine:
for(int i = 0; i < 10; i+=1){
	if(i%2 == 0)
		even += digit;
	else
		odd += digit;
	suspend() // get next digit
}

Rewrite the loop body to use the “Zen” of the coroutine, i.e., let the coroutine do the work.

for ( int i = 0; i < 5; i += 1 ) { 
	even += digit;
	suspend();
	odd += digit;
	suspend()
}
  • d) i. 2 marks Explain the terms stackless and stackful coroutine.
    • stackless uses the caller’s stack and a fixed-sized local-state. stackful has a separate stack and a fixed-size (class) local-state
    • ii. 2 marks Which is more powerful and why?
      • stackful allows helper routines with suspends (refactoring) and full coroutining
  • e) 1 mark Why are non-local exceptions among coroutines difficult to program?
    • Non-local exceptions require a coroutine to be resumed before it can receive the exception.

3

  • a) 1 mark Explain the term preemptive scheduler.
    • If interrupts affect scheduling (execution order), it is called preemptive.
  • b) 1 mark What is wrong with this statement: When a thread unblocks it starts running.
    • A thread cannot bypass the ready state during a state transition.
    • In reality, when a thread unblocks, it moves to the ready state, not directly to the running state. This means the thread is now eligible to run, but it must wait for the scheduler to select it from the ready queue before it can actually start executing. A thread cannot bypass the ready state and transition directly from blocked to running; it must go through the ready state first.
  • c) 2 marks Why do most concurrent programs have non-linear program speedup.
    • Answer: 2. As CPUs are added, speedup starts sub-linear because of concurrency overhead but then hits a bottleneck becoming non-linear as it levels out and possibly drops