本文概括敘述了一篇老文的內(nèi)容,并且總結(jié)對(duì)malloc返回值的3種轉(zhuǎn)型方式,(相對(duì)于原文)更全面的總結(jié)其各自的應(yīng)用范圍。
1. 原文內(nèi)容
2. 對(duì)malloc的3種轉(zhuǎn)型方式
3. 各自的應(yīng)用范圍
以前有篇文章叫《C/C++ 誤區(qū) —— 強(qiáng)制轉(zhuǎn)換 malloc() 的返回值》。
文章大致內(nèi)容是:
1. malloc函數(shù)在<stdlib.h> 或者 <cstdlib>頭文件中,而不是<malloc.h>。
2. 由于C語(yǔ)言最初沒(méi)有void類(lèi)型,所以是使用char*來(lái)代表通用指針。
/* the old declaration of malloc */
char* malloc(size_t size);
char* p = malloc(size * sizeof(*p) );
/* 可以, 不需要轉(zhuǎn)型 */
T1* p1 = malloc(size1 * sizeof(*p1) );
/* (T1!=char) 不可以,char*不能隱式轉(zhuǎn)換成T1* */
T2* p2 = (T2*)malloc(size2 * sizeof(*p2) );
/* (T2!=char) 可以,顯示類(lèi)型轉(zhuǎn)換 */
3.C語(yǔ)言后來(lái)引入了void類(lèi)型,就可以使用void*代表通用指針,同時(shí)規(guī)定void*可以隱式轉(zhuǎn)換到任意指針類(lèi)型。
/* the new declaration of malloc */
void* malloc(size_t size);
char* p = malloc(size * sizeof(*p) );
/* 仍然可以,void*可以隱式轉(zhuǎn)換到任意指針類(lèi)型 */
T1* p1 = malloc(size1 * sizeof(*p1) );
/* 現(xiàn)在可以,void*可以隱式轉(zhuǎn)換到任意指針類(lèi)型 */
T2* p2 = (T1*)malloc(size2 * sizeof(*p2) );
/* 仍然可以,但不再必須 */
4. 在引入了void之后的C語(yǔ)言中,再使用強(qiáng)制轉(zhuǎn)換是畫(huà)蛇添足,同時(shí)影響代碼維護(hù)。
并且說(shuō)這是一個(gè)C/C++的
誤區(qū)。
原文概述完畢,開(kāi)始說(shuō)本文章的內(nèi)容:
對(duì)malloc返回值的轉(zhuǎn)型,大致有以下三種方式:
1. 僅在C中
/* legal only in C */
/* 新頭文件 */
T* p = malloc(size * sizeof(*p) ); /* T!=void */
/* 舊頭文件 */
T* p = (
T*)malloc(size* sizeof(*p) ); /*
T!=
void */
2.僅在C++中
C++天然支持void,但是不允許void*隱式轉(zhuǎn)換到任意類(lèi)型指針,需要static_cast。
// legal only in C++
// 新頭文件
T* p = static_cast<T*>( malloc(size * sizeof(*p) ));
// 舊頭文件(目前還有這種編譯器嗎?)
T* p = reinterpret_cast<T*>( malloc(size * sizeof(*p) ));
// 當(dāng)然在C++中應(yīng)該考慮
T* p = new T[size];
// 或者
std::vector<T> p(size);
// 但這不是文章討論重點(diǎn)
3.在C/C++中
/* legal in both C and C++ */
/* legal in both new and old header */
T* p = (T*)malloc(size * sizeof(*p) );
第1種對(duì)新頭文件的轉(zhuǎn)型方式,如同代碼第1行所說(shuō),僅在C編譯器中合法。
因?yàn)镃++不支持void*到其他指針類(lèi)型的隱式轉(zhuǎn)換。
所以,原文章說(shuō)這是C/C++的誤區(qū),并不準(zhǔn)確。
這僅僅是(引入void類(lèi)型之后的)C語(yǔ)言中的“非必須”的動(dòng)作,是否是誤區(qū),還有待考量。
第2種對(duì)新舊頭文件的轉(zhuǎn)型方式,代碼第1行也說(shuō)了,僅在C++編譯器中合法。
因?yàn)镃編譯器不認(rèn)識(shí)static_cast或者reinterpret_cast。
第3種,是一種中庸的寫(xiě)法。
如同代碼第1行所說(shuō):此代碼無(wú)論是在C還是C++編譯器,無(wú)論是新頭文件還是舊頭文件,都是合法的代碼。是可移植性最好的代碼。
因?yàn)榇a中使用的(C風(fēng)格的)轉(zhuǎn)型、malloc——C/C++都支持。
所以,這種寫(xiě)法并不一定是誤區(qū)或者畫(huà)蛇添足。
因?yàn)榇a的作者也許比原文章的作者對(duì)移植性(C和C++的新舊編譯器)考慮更多。
一個(gè)排版比較好的原文轉(zhuǎn)載鏈接
http://programmingart.blog.51cto.com/213782/43503
posted on 2009-03-06 10:16
OwnWaterloo 閱讀(4143)
評(píng)論(4) 編輯 收藏 引用