2008-12-17 84 views
20

最近看到有人讚揚另一位用戶使用sizeof var而不是sizeof(type)。我一直認爲這只是一種風格選擇。有什麼重要的區別?作爲一個例子,用f和FF線被認爲是比G和GG線更好:「C」sizeof與類型或變量

typedef struct _foo {} foo; 

foo *f = malloc(count * sizeof f); 
foo *g = malloc(sizeof(foo) * count); 

foo **ff = malloc(count * sizeof *ff); 
foo **gg = malloc(sizeof(foo*) * count); 

在我看來,第一套僅僅是一個風格問題。但是在第二對線中,額外的第二個*很容易被乘法混淆。

+3

您在第一個`malloc`行有錯誤 - 它應該是`sizeof * f`。一般模式是`somevar = malloc(count * sizeof * somevar)`。 – caf 2009-12-22 05:13:56

回答

45

如果變量的類型改變了,如果變量是參數而不是類型,sizeof將不需要改變。

關於@ icepack的評論:類型與變量名稱的變化的可能性或可​​能性不是問題。想象一下,變量名用作sizeof的參數,然後再改變。在最好的情況下,重構重命名操作會改變所有事件並且不會引入錯誤。在最糟糕的情況下,sizeof的一個實例被遺漏,編譯器會抱怨並且你修復它。如果類型更改完成,則sizeof語句不會出現錯誤。

現在想象這個類型是sizeof的參數。如果變量的類型發生了變化,除了檢查以外,沒有其他辦法可以查找與該變量相關的所有sizeof。你可以搜索,但你會得到相同類型的sizeof的所有無關用途的點擊。如果錯過了一個,由於尺寸不匹配,您將會遇到運行時問題,這更加麻煩。

+1

對於數組變量,sizeof(array)會給你數組的實際大小。它可以用來計算元素sizeof(array)/ sizeof(element)的個數。請注意,它不適用於通過指針分配的內存。 – 2008-12-17 07:24:00

+2

不是一個合理的論點。以同樣的方式可以聲稱,如果變量的名稱被改變,如果類型是參數而不是變量,sizeof將不需要改變。更改的可能性取決於特定的設計(並且在大多數情況下都不會或應該改變) – SomeWittyUsername 2012-12-08 08:25:57

+0

這個答案似乎並不是一個「最終」的解決方案,牢記它不包括代碼邏輯依賴於typedef的情況在一個特定的變量上。你可以在下面看到我的答案。 – Riga 2014-05-20 11:13:18

3

行f和ff肯定比g和gg差。 sizeof f是指針大小,因爲f是一個點。爲了使它們等價,你必須寫sizeof *f(或者爲了更好的可讀性,sizeof(*f))。

6

除了史蒂夫說的,讓我補充一點,sizeof不會評估它的操作數。所以你可以自由地做任何事情。不僅可以使用尚未初始化的變量,還可以取消引用空指針,調用未定義的函數,但只聲明並執行任何其他類型的東西。我鼓勵你總是使用表達式版本,因爲史蒂夫很好地解釋了這一點。

另外考慮到有時候typenames真的很長且不可讀,只是想到指向函數的指針(特別是在C++中)。而不是寫sizeof(my_long_type<weird, stuff>)你只是做sizeof t

+0

4年過去了,C++中的long類型名稱問題已經被`decltype`減少了:) – SomeWittyUsername 2012-12-08 08:28:34

0

考慮變量的大小可能會有意想不到的結果。當變量是數組時,sizeof(array)將返回數組的大小,而不是單個元素的大小或指針的大小。取指針的大小將返回指針的大小。但是由於數組在傳遞時通常表示爲指針,因此可能會引起混淆。

2

我傾向於在內存分配中使用sizeof(type),但在使用本地或全局變量時總是使用sizeof(variable)。儘管如此,建議中總是有智慧使用變量名稱。

我也有過很長時間的討論(相當於有時會動畫,持續了幾天 - 我們最終同意在這個問題上有所不同),關於是否可以使用sizeof(variable)或者它是否必須是sizeof variable;也就是說,括號是否包含sizeof的參數是否重要?我從來沒有遇到過一個編譯器,該編譯器的威脅大約是sizeof(variable),所以我選擇統一性,並始終使用sizeof的括號。我的同事同樣堅持認爲括號不能用於變量;無論如何,在帶括號和不帶括號的符號之間都存在着有價值的區別。我沒有被說服 - 我不希望被說服。

在一個完全不同的策略,一個關於sizeof其他幾個要點:

  • 如果您使用C99和VLA - 變長數組 - 然後sizeof(vla)是不是編譯時間常數。謹防!
  • C預處理器不理解sizeof這是一個令人討厭但邏輯。
4

您可能會看到這些差別不大:

foo **ff = malloc(count * sizeof *ff); 
foo **gg = malloc(sizeof(foo*) * count); 

..但如果什麼配置是不是附近的聲明?如果我遇到這樣一行:

ff = realloc(ff, count * sizeof *ff); 

那麼我有理由相信該行是正確的,甚至沒有記住的ff類型。但是,如果我看到這一點:

ff = realloc(ff, count * sizeof(foo *)); 

那麼我可能有點可疑,並需要查找的ff類型把我放心了。

0

業務邏輯定義您的選擇。

  1. 如果你的代碼是指一個特定的變量,如果沒有這個變量的代碼是沒有意義的 - 選擇sizeof(var)

  2. 如果你有一組特別的類型變量代碼的交易 - 選擇sizeof(type)。 如果你有一個typedef,通常你需要這個,它定義了許多你根據它們的類型處理不同的變量(例如序列化)。您可能不知道哪些變量將保留在將來的代碼版本中,因此選擇type作爲參數在邏輯上是正確的。即使更改此類typedef也不會影響您的sizeof系列。