7 回答

TA貢獻1856條經驗 獲得超11個贊
無 ; 你沒有投射結果,因為:
這是不必要的,因為
void *
在這種情況下自動且安全地提升到任何其他指針類型。它增加了代碼的混亂,轉換不是很容易閱讀(特別是如果指針類型很長)。
它讓你重復自己,這通常很糟糕。
如果您忘記包含,它可以隱藏錯誤
<stdlib.h>
。這可能會導致崩潰(或更糟的是,不導致崩潰,直到方式在后面的代碼的一些完全不同的部分)。考慮如果指針和整數的大小不同會發生什么; 那么你通過強制轉換隱藏了一個警告,可能會丟失你返回的地址。注意:從C11開始,隱式函數從C中消失,并且這一點不再相關,因為沒有自動假設未聲明的函數返回int
。
作為澄清,請注意我說“你不投”,而不是“你不需要投”。在我看來,即使你做對了也沒有包括演員。這樣做沒有任何好處,但是一堆潛在的風險,包括演員表明你不知道風險。
還要注意,正如評論員指出的那樣,上面談的是直C,而不是C ++。我非常堅信C和C ++是不同的語言。
要進一步添加,您的代碼會不必要地重復int
可能導致錯誤的類型信息()。最好取消引用用于存儲返回值的指針,將兩者“鎖定”在一起:
int *sieve = malloc(length * sizeof *sieve);
這也會移動length
到前面以增加可見性,并刪除多余的括號sizeof
; 只有在參數是類型名稱時才需要它們。許多人似乎不知道(或忽略)這一點,這使得他們的代碼更加冗長。記?。?code>sizeof不是功能!:)
雖然移動length
到前面可能會增加在某些極少數情況下的可見性,但是在一般情況下,應該注意將表達式編寫為:
int *sieve = malloc(sizeof *sieve * length);
因為sizeof
在這種情況下保持第一個,所以確保乘法至少用size_t
數學來完成。
比較:malloc(sizeof *sieve * length * width)
與malloc(length * width * sizeof *sieve)
第二個可能溢出的length * width
時間width
和length
比較小的類型size_t
。

TA貢獻1869條經驗 獲得超4個贊
在C中,您不需要轉換返回值malloc
。返回的void指針malloc
自動轉換為正確的類型。但是,如果您希望使用C ++編譯器編譯代碼,則需要進行強制轉換。社區中的首選替代方案是使用以下內容:
int *sieve = malloc(sizeof *sieve * length);
如果你改變了類型,你還可以免去擔心改變表達式的右側sieve
。
人們已經指出,演員陣容很糟糕。特別是指針轉換。

TA貢獻1830條經驗 獲得超3個贊
你做演員,因為:
它使您的代碼在C和C ++之間更具可移植性,并且正如SO經驗所示,許多程序員聲稱他們在用C ++(或C加本地編譯器擴展)編寫時正在用C語言編寫。
如果不這樣做可以隱藏錯誤:注意所有的混亂的SO例子,當寫
type *
對type **
。它讓你不會注意到你沒有找到
#include
合適的頭文件的想法錯過了森林的樹木。這就像說“不要擔心你沒有要求編譯器抱怨沒有看到原型這一事實 - 那令人討厭的stdlib.h是真正重要的事情要記住!”它強制進行額外的認知交叉檢查。它將(聲稱的)所需類型放在您正在為該變量的原始大小進行的算術旁邊。我敢打賭你可以做一個SO研究,它表明
malloc()
當有一個演員時,bug會被抓得更快。與斷言一樣,顯示意圖的注釋可以減少錯誤。以機器可以檢查的方式重復自己通常是一個好主意。事實上,這就是一個斷言,并且使用強制轉換是一種斷言。斷言仍然是我們獲得正確代碼的最常用技術,因為圖靈在很多年前提出了這個想法。

TA貢獻1802條經驗 獲得超6個贊
正如其他人所說,C不是必需的,而是C ++。如果您認為要使用C ++編譯器編譯C代碼,出于某種原因,您可以使用宏,例如:
#ifdef __cplusplus# define NEW(type, count) ((type *)calloc(count, sizeof(type)))#else# define NEW(type, count) (calloc(count, sizeof(type)))#endif
這樣你仍然可以以非常緊湊的方式編寫它:
int *sieve = NEW(int, 1);
它將為C和C ++編譯。

TA貢獻1801條經驗 獲得超8個贊
在C中,您可以隱式地將void指針轉換為任何其他類型的指針,因此不需要強制轉換。使用一個人可能會向不經意的觀察者建議,有一些理由需要一個,這可能會產生誤導。

TA貢獻1821條經驗 獲得超5個贊
你沒有強制轉換malloc的結果,因為這樣做會給你的代碼帶來無意義的混亂。
人們投射malloc結果的最常見原因是因為他們不確定C語言是如何工作的。這是一個警告信號:如果您不知道特定語言機制的工作原理,那么請不要猜測。查找或詢問Stack Overflow。
一些評論:
可以將void指針轉換為/從任何其他指針類型轉換而不進行顯式轉換(C11 6.3.2.3和6.5.16.1)。
但是,C ++不允許在
void*
另一個指針類型之間進行隱式轉換。所以在C ++中,演員陣容是正確的。但是如果你用C ++編程,你應該使用new
而不是malloc()。而且你永遠不應該使用C ++編譯器編譯C代碼。如果需要使用相同的源代碼同時支持C和C ++,請使用編譯器開關來標記差異。不要嘗試使用相同的代碼來區分兩種語言標準,因為它們不兼容。
如果C編譯器由于忘記包含頭而無法找到函數,那么您將收到編譯器/鏈接器錯誤。因此,如果您忘記包含
<stdlib.h>
那些沒什么大不了的話,那么您將無法構建您的程序。對于遵循超過25年的標準版本的古代編譯器,忘記包含
<stdlib.h>
將導致危險的行為。因為在那個古老的標準中,沒有可見原型的函數隱式地將返回類型轉換為int
。然后顯式地從malloc轉換結果將隱藏此錯誤。但這確實不是問題。您沒有使用25年的計算機,那么為什么要使用25年的編譯器呢?
- 7 回答
- 0 關注
- 651 瀏覽
添加回答
舉報