![]() |
.. (לתיקייה המכילה) | |
What is the default value for an enum variable that was declared but not defined yet? | |
The default value in this case would be the first value in the definition of that enum type. For example: enum days {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}; enum days d; \\default value is SUNDAY |
How many registers are we allowed to use during the evaluation of a boolean expression? | |
**Clarification** For evaluating boolean expressions we advise you to use a series of jumps and backpatching as we saw in class (with support for short circuit-evaluation of course). Note that for each jump in the series of jumps mentioned above you will have to use a register to store the condition value for the conditional branch. This is OK (we did not count those registers in our original answer). Also note - we *won't* manually check how many registers you have used in your implementation for this purpose but we do encourage you to implement this as we learned in class - trust us, it will make your life easier. |
Should we use 'sdiv' or 'udiv' for division? | |
For this exercise use 'sdiv'. **Clarification** Because LLVM integers use a two’s complement representation, when dividing two *byte type* values make sure that you sign extend your i8 operands first *before* using 'sdiv' (otherwise you might get a wrong result in some cases). To sign extend your operands you can use the 'zext' instruction which was mentioned in the HW instructions. Example: void main() { printi(200b/5b); //should print: 40 } Note that this is *only* relevant for those of you who chose to represent byte values as i8 in their implementation. The simpler and *recommended* way to prevent these issues in the first place is to simply represent all numerical values in your implementation as i32, and then after each operation to truncate the result if necessary according to the desired type. |
Are we supposed to catch and report every possible division be zero error? | |
Yes. Note that this error should be detected and reported at *runtime*, and *not* during the compilation process (why?). This means that your compiler should generate LLVM code which at runtime, before every division command, checks whether the divisor is equal to zero, and if it is prints the required error and exits the program. Note that in order to terminate the program in such cases (after printing the error) you can use the C function ‘exit’. In order to use it you must add its declaration to your LLVM code (you can find the declaration in the HW instructions pdf). |
Is it legal to change the values of a function’s parameters inside the function? | |
Yes. Think how you can add support for this feature in your implementation (hint – this is not very different from how you treat local variables). For example this code is legal: int inc(int x) { x = x + 42; // this is ok return x; } Note – unlike the function’s local variables, which are limited in this exercise to a max of 50, a function can have an *unlimited* number of parameters. Also note – all function arguments are passed *by value*. |
Will you check the exercise for memory leaks with tools such as Valgrind? | |
The answer is no, but it is your responsibility to make sure that your submission does not crash due to memory issues. |
In HW3 you instructed us to ignore cases where non-void functions do not have a return statement. How should we treat such cases in this exercise? | |
In this exercise please assume the following in regard to the programs we might use to test you implementation with: - Every non-void function will have a return statement (although it might not be semantically correct). - A void function might *not* have a return statement. *Clarification*: For non-void functions you can assume that *every* exit path will have a return statement (although it might not be semantically correct), even if that path is unreachable. |
Why can’t we just use LLVM’s temporary variables for the local variables instead of storing them on the stack? | |
Although it might seem at first like it is possible to avoid using the stack altogether, when you get to implementing the more advanced parts of the exercise (like the if-else statement) you will understand why this is not the case. Note that in some cases using the command 'phi' (you can read about it if you want) might be able to help resolve these issues, but usually it won't be so simple. The bottom line is - use the stack :) (It's not very complicated). |