# 2021q1 Homework5 (quiz5)
contributed by < `gyes00205` >
###### tags: `linux2021`
> [題目](https://hackmd.io/@sysprog/linux2021-quiz5)
## 測驗 `1`
#### `#define NEXT_POWER_OF_2(s)`
找出大於等於 `s` 且為 2 的冪的數值。 `s` 為 2 的冪時才會回傳 s 。
```cpp
#define NEXT_POWER_OF_2(s) \
!(s & (s - 1)) ? s : (size_t) 1 << (64 - __builtin_clzl(s))
```
e.g. `NEXT_POWER_OF_2(8)`
$s$ $=$ $8$ $=$ $1000_2$ , $s - 1$ = $0111_2$
!($s$ & $(s - 1)$) = !($0000_2$) 非零
最後回傳 $s$ $=$ $8$
#### `#define vec_pop_back(v)`
從 vector 最後面 pop 一個元素出來。所以 size - 1 , capacity 不會改變。
```cpp
#define vec_pop_back(v) (void) (v.size -= 1)
```
#### `__vec_push_back`
如果 v->size 等於 capacity 需要增加記憶體空間。
因此 VV3 為 `elemsize * (size_t) 1 << ++v->capacity` 。要乘上 elemsize 。
```cpp
static NON_NULL void __vec_push_back(void *restrict vec,
void *restrict e,
size_t elemsize,
size_t capacity)
{
union {
STRUCT_BODY(char);
struct {
size_t filler;
char buf[];
};
} *v = vec;
if (v->on_heap) {
if (v->size == capacity)
v->ptr = realloc(v->ptr, elemsize * (size_t) 1 << ++v->capacity);
memcpy(&v->ptr[v->size++ * elemsize], e, elemsize);
} else {
if (v->size == capacity) {
void *tmp =
malloc(elemsize * (size_t) 1 << (v->capacity = capacity + 1));
memcpy(tmp, v->buf, elemsize * v->size);
v->ptr = tmp;
v->on_heap = 1;
memcpy(&v->ptr[v->size++ * elemsize], e, elemsize);
} else
memcpy(&v->buf[v->size++ * elemsize], e, elemsize);
}
}
```