[英]Is it good style to memset a struct before using it?
一旦我學會了信號,便有了處理信號的清單。
有一個struct sigaction
,它是第一個memset()
到所有字節為零的以下行:
memset(&sa, 0, sizeof(sa));
而且我不確定為什么作者使用這種方法。
正如您已經被告知的那樣,嘗試從結構的未初始化成員中讀取值會導致未定義的行為。 那是無條件的壞。 因此,您有責任確保在讀取所有字段之前對其進行初始化。
如果您知道該結構的所有元素並打算顯式初始化它們,則不需要memset()
。 如果結構處於您的控制之下,那么這是可以管理的-您只需記住要確保在向結構中添加新成員時,所有初始化發生的位置都得到了更新。 如果編寫一個函數來做到這一點(想想“ C ++構造函數的C類似物”,第一次近似),那么memset()
。 如果您在許多地方臨時設置值,則結構更改可能會出現問題。
對於諸如struct sigaction
類的東西,它來自系統定義的頭文件,並且不同的系統可以(並且確實)向結構中添加額外的字段-除了計划初始化的字段。 請注意,POSIX僅指定必須存在的字段。 它不決定字段的順序,也不要求結構中沒有其他字段。 但是,使用結構的多余(非POSIX)元素的函數不應該這樣做,除非用戶指示通常使用一些顯式標志初始化那些成員,這樣就不會遇到問題-但這樣做更安全比對不起。
因此,在您無法控制結構的情況下, memset()
方法很容易辯護:即使結構定義發生了變化,也可以保證將所有結構(即使您不知道的位)都清零。 (編寫代碼后)。
您可能可以使用struct sigaction sa = { 0 };
或struct sigaction *sap = calloc(sizeof(*sap), 1);
將結構改為零,這部分取決於您使用的一組編譯器選項的復雜程度(以及所使用的編譯器的版本;例如,GCC隨着時間的推移已更改其行為)。
您可能想要在POSIX標准中查找諸如PTHREAD_MUTEX_INITIALIZER
宏,或者您可能希望完全忽略它們的存在。
未初始化的變量包含不確定的值,使用它們通常是導致程序失敗的原因,因此您需要在使用變量之前對其進行初始化。 但是您不必使用memset
即可,可以使用初始化器:
struct sigaction sa = {0};
這樣,可以保存函數調用,並且代碼閱讀器可以輕松地發現它已被初始化。
當您聲明沒有初始化程序的struct
,使用該struct
的任何成員而不先分配它們是未定義的行為。 如果您希望將零放入struct
所有成員中,那么memset
提供了一種很好的方法。
如果您仍然計划分配該struct
所有成員,則無需調用memset
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.