# 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()`