contributed by < AmyLin0210
>
2021q1 Linux
xs
是一個有 16 byte 的 union,分成三個部份:
小字串:字串長度小於等於 15 ,儲存於 stack
15 - space_left
data
字元陣列中中字串:
size
內長字串:
size
內_Static_assert 的用途為編譯時期檢測錯誤,若是 expression 等於 0 ,會出現 compile-time error
。
_Static_assert ( expression , message )
The constant expression is evaluated at compile time and compared to zero. If it compares equal to zero, a compile-time error occurs and the compiler must display message (if provided) as part of the error message (except that characters not in basic source character set aren't required to be displayed).
Otherwise, if expression does not equal zero, nothing happens; no code is emitted.
現在我把 xs_tmp
簡化並改寫為以下:
由於 xs_new(&xs_literal_empty(), x)
最終會回傳出 xs
型態的數值,為了實驗方便,現在處理的數值型態皆為 integer
想到那是否也可以將 macro 簡化為
測試:
在上面測試第 2 行的部份讓我感到不解,又測試了其他的寫法:
可以發現給 a 的值皆為括號的最後面。
由 tiffany6022 同學的筆記中得知,原來這是使用了 comma operator 的結果
在這邊使用到了 Compound Literals 來對 struct 做初始化。
xs_new
把字串儲存方式依照長度分類:
TODO: 用 GDB 確認上述程式碼實際的運作,是否符合預期,可善用 x
命令
在使用 gdb 查看的過程中發現最後一個 byte 中 space_left
的位置應為最後的 4 個 bits。
我使用了 rbp
與 rsp
來分別印出 stack 的底部與頂部,可以發現在 short
短字串中,他的資料被儲存於 stack ,而 mid
中字串則被儲存於 heap。
xs_allocate_data
在這裡將字串分別處理中字串以及長字串,差別在於中字串直接儲存字串的位置,長字串在 ptr
的最前面 4 個 byte 預留空間儲存 reference count。
xs_data
取出儲存於 heap 空間內的字串,也就是中字串及長字串。
由於長字串的最前面 4 個 byte 用來儲存 reference count ,因此須從指標開始的第四個位置開始取值。
xs_trim
函式的目標為將指定字串中頭尾含有 trimset
內的字元給移除。
xs_cow_lazy_copy
檢查 x
的 reference count 是否大於 1 ,
若大於 1 ,表示有一個以上的指標指向該字串的位置。
在 reference count 大於一的情況下,需要額外 malloc 出空間,複製一份相同內容的字串來改動。
xs_allocate_data
malloc 出一個新的存字串的位置data
內的字串複製進 x
剛剛創建空間data
指向 x
內字串指標的位置xs_dec_refcnt
將 x
的 reference count 減 1
xs_concat
在第 4 行中的 capacity 會計算出目前字串 string
的長度限制,以下分成兩個狀況討論:
capacity
string
內的空間中。capacity
xs tmp
,給予它足夠儲存新字串的空間xs tmp
的空間內xs string
指向的空間 free 掉,將其指向 tmp
memmove v.s memcpy
以上節錄自 memmove 與 memcpy 的 Linux Programmer's Manual
在 xs_concat
第 12 行的地方目標是將 data
往後位移 pres
個位置,若 pres
小於 size
, src 與 dist 將有可能重疊,所以才必須使用 memmove
而非使用 memcpy
xs_capacity
x
內的字串放置於 stack 空間,回傳 15x
內的字串放置於 heap 空間,回傳 - 1xs_grow
在這邊有兩種情況需要被討論
在程式碼中的第 16 行目標為檢查字串是否儲存於 heap,但由於第 13 行已經先把 is_ptr
改為 true
故永遠為真,因此需要修改程式碼為以下: