# jserv office hour 5/30 (Sun) :::info office hour 問題 1. rio_package * in `csapp.h` * `Rio_readlineb()`, `rio_readlineb()` `read()` 差別 * 已知: Rio_readlineb() 是個 wrapper ```cpp ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) { ssize_t rc; if ((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0) unix_error("Rio_readlineb error"); return rc; } ``` * 呼叫 `rio_readlineb()` 時如果發生錯誤,就跳出 `unix_error()` * 為什麼需要設計這麼多 function 不整合成一個 function 執行速度比較快 * rc 的意義是什麼? * 我的猜測 * reference counting? * But what does it mean? 2. linenoise autocompletion - 要如何得知鍵盤輸入什麼東西,在按下 Enter 之前就觸發 TAB? * 找到的關鍵字: escape sequence * [in linenoise.c 的註解](https://github.com/antirez/linenoise/blob/master/linenoise.c) * 但不清楚他在做什麼 3. 為什麼我們需要 Callback function? * 已知的應用: signal ```cpp SYNOPSIS #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); ``` * 但不知道他跟一般 function 差別 * 已做的實驗 * 在底下 ::: ## Callback function 與 一般 function 的差別 Ref: [StackOverflow](https://stackoverflow.com/questions/30403678/callback-function-vs-ordinary-function-in-c) :::warning Question: 為什麼下列程式需要多一層 `call_func()` 來呼叫真正做事的函式 `add_two_number() `呢? 他與直接呼叫 `add_two_number() ` 的差別在哪? ::: ### Code ```cpp #include <stdio.h> int add_two_number(int a, int b); int sub_two_number(int a, int b); int call_func(int (*ptr_func)(int, int), int a, int b); int main (int *argc, char *argv[]) { // Here is where we decide what the function should do for the first call printf("%d", call_func(add_two_number, 5, 9)); // Here is where we decide what the function should do for the second call printf("%d", call_func(sub_two_number, 5, 9)); return 0; } int add_two_number(int a, int b) { return a + b; } int sub_two_number(int a, int b) { return a - b; } int call_func(int (*ptr_func)(int, int), int a, int b) { return ptr_func(a, b); // Here is the place the call is made } ``` ### GDB test 僅測試兩數相加的部分 ```gdb (gdb) b call_func Breakpoint 1 at 0x6eb: file callback.c, line 28. (gdb) r Starting program: /home/ubuntu/xxx/callback/callback Breakpoint 1, call_func (ptr_func=0x5555555546b3 <add_two_number>, a=5, b=9) at callback.c:28 28 return ptr_func(a, b); // Here is the place the call is made (gdb) b add_two_number Breakpoint 2 at 0x5555555546bd: file callback.c, line 18. (gdb) b sub_two_number Breakpoint 3 at 0x5555555546d1: file callback.c, line 23. (gdb) r Starting program: /home/ubuntu/xxx/callback/callback Breakpoint 1, call_func (ptr_func=0x5555555546b3 <add_two_number>, a=5, b=9) at callback.c:28 28 return ptr_func(a, b); // Here is the place the call is made (gdb) n Breakpoint 2, add_two_number (a=5, b=9) at callback.c:18 18 return a + b; (gdb) info stack #0 add_two_number (a=5, b=9) at callback.c:18 #1 0x00005555555546fb in call_func (ptr_func=0x5555555546b3 <add_two_number>, a=5, b=9) at callback.c:28 #2 0x0000555555554670 in main (argc=0x1, argv=0x7fffffffe4d8) at callback.c:10 ``` * 為什麼需要多一層 `call_func()` 來呼叫真正做事情的 `add_two_number()` 呢? 以 stack 來觀察 * `main()` * `call_func()` * `add_two_number()` * `call_func()` * `main()` * `call_func()` * `sub_two_number()` * `call_func()` * `main()` * 為什麼不直接 * `main()` * `add_two_number()` * `main()` * `sub_two_number()` * `main()`